随身笔记
随身笔记

为移动端rem单位解决方案——flexible.js

方案一:

在所有的css和js最先引入

flexible_css.js,flexible  有样式版本

flexible   无样式版本

http://g.tbcdn.cn/mtb/lib-flexible/0.3.4/??flexible_css.js,flexible.js

假如设计师给来的设计稿是宽375px那么,100px/37.5=2.6666666667rem

如果设计稿是750px,那么100px/75单位rem

甚至连viewport和初始化样式都不用设置了,引入的链接已经帮我们设置好了初始化样式和动态设置viewport

 

深入理解rem原理,rem单位是相对单位,是相对于html的font-size

把屏幕分成10等分,屏幕宽以375px为基准,每一份是37.5px,1份就是1rem

<html lang=”en” style=”font-size: 37.5px”>

https://sdeno.com/wp-content/uploads/2019/04/微信图片_20240407155836.png

画图就很好理解了,在去了解这句话:假如设计师给来的设计稿是宽375px那么,100px/37.5=2.6666666667rem,

只要把元素的rem值计算好之后,html的font-size值都会随着屏幕宽度变化,元素大小也会成比例放大缩小

 

 

实例:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<!-- 去掉meta,交给flexible.js自动处理 -->
<!-- <meta name="viewport" content="width=device-width, initial-scale=1.0" /> -->
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
<script src="./js/flexible.js"></script> 
<link rel="stylesheet" href="./css/index.css" rel="external nofollow" />  <!--如果引入有样式的flexible.js,连初始化css都可以不用写-->
</head>
<body>
 <div class="wrap">
 <div class="title">首页</div>
</div>
</body>
</html>

 

//index.css,样式简单暴力的初始化

html,
body {
 margin: 0;
 padding: 0;
}

 

 

vue-cli4部署

1,

npm install lib-flexible --save 
npm install postcss-px2rem --save

 

 

2,在main.js中引入lib-flexible

import 'lib-flexible'

 

 

3,编辑vue.config.js

module.exports = {
 .
 .
 css: {
  loaderOptions: {
    css: {},
    postcss: {
      plugins: [
        require('postcss-px2rem')({
          remUnit: 37.5 //设计图给的375px的图,100px的话,那么100/37.5rem
        })
      ]
    }
  }
 }

}

 

这里有一个问题如果样式是写在js中如何适配?,解决方法如下:

这里以1920为案例,如果浏览器窗口是全屏那么值就是1,缩小会按比例显示

setHtmlSize() {
      let defaultWidth = 1920;
      let defaultFontSize = 100;
      let minWidth = 1200;
      let wd = document.body.clientWidth;
      let fontSize;
      let globalScale = wd / defaultWidth;

      if (wd > defaultWidth) {
        fontSize = defaultFontSize;
      } else if (wd < minWidth) {
        globalScale = minWidth / defaultWidth;
        fontSize = (minWidth / defaultWidth) * defaultFontSize;
      } else {
        fontSize = (wd / defaultWidth) * defaultFontSize;
      }
      
      console.logg(globalScale) //这里就是获取缩放屏幕比例的值
      // document.querySelector('html').style.fontSize = fontSize + 'px';
},


this.setHtmlSize()

window.addEventListener('resize', ()=>{
   this.setHtmlSize()
});

 

 

 

也可参考:《vuelic脚手架适配移动端解决方法rem》

 

方案二:

<style>
    *{margin: 0;padding: 0;}
</style>
<script>
    ;(function(win) {
        var docEl = win.document.documentElement,
            tid;

        function refreshRem() {
            var width = docEl.getBoundingClientRect().width;
            var rem = width / 750*100;//以750px为原稿,除以100可得各元素的rem
            docEl.style.fontSize = rem + "px";
            var actualSize = parseFloat(window.getComputedStyle(docEl)["font-size"]);
            if (actualSize !== rem) {
                var remScaled = rem / ( actualSize / rem );
                docEl.style.fontSize = remScaled + "px"
            }
        }

        function dbcRefresh() {
            clearTimeout(tid);
            tid = setTimeout(refreshRem, 100)
        }

        win.addEventListener("resize", function() { dbcRefresh() }, false);
        win.addEventListener("pageshow", function(e) {
            if (e.persisted) { dbcRefresh() }
        }, false);
        refreshRem();
    })(window);
</script>

如果设计给平面图宽度是750px  一个图片宽是200px,那么样式就是200/100=2rem

如果设计给375px  一个图片宽是100px,那么样式就是100/100*2=2rem

 

 


先了解rem单位作用:

1,rem 可以控制字体大小、宽、高。栅格布局推荐使用百分比来控制
2,rem大小都是相对于html font-size的值来确定的

例如,
html如果不设置font-size那么默认是16px
1rem=16px

如果设置font-size:17px
1rem=17px

如果以html font-size:17px为准,某一个元素宽高都是100px的话,那么计算成rem就要100除以17

 

为了避免这样麻烦的计算,即使使用css的媒体查询也要针对很多不同手机屏幕设置还要做出很多添加修改,所以考虑使用js来完成。

页面前面添加:

//designWidth:设计稿的实际宽度值,需要根据实际设置
//maxWidth:制作稿的最大宽度值,需要根据实际设置
//这段js的最后面有两个参数记得要设置,一个为设计稿实际宽度,一个为制作稿最大宽度,例如设计稿为750,最大宽度为750,则为(750,750)
;(function(designWidth, maxWidth) {
  var doc = document,
      win = window,
      docEl = doc.documentElement,
      remStyle = document.createElement("style"),
      tid;

  function refreshRem() {
     var width = docEl.getBoundingClientRect().width;
     maxWidth = maxWidth || 540;
     width>maxWidth && (width=maxWidth);
     var rem = width * 100 / designWidth;
     remStyle.innerHTML = 'html{font-size:' + rem + 'px;}';
  }

  if (docEl.firstElementChild) {
     docEl.firstElementChild.appendChild(remStyle);
  } else {
     var wrap = doc.createElement("div");
     wrap.appendChild(remStyle);
     doc.write(wrap.innerHTML);
     wrap = null;
  }
  //要等 wiewport 设置好后才能执行 refreshRem,不然 refreshRem 会执行2次;
  refreshRem();

  win.addEventListener("resize", function() {
    clearTimeout(tid); //防止执行两次
    tid = setTimeout(refreshRem, 300);
  }, false);

   win.addEventListener("pageshow", function(e) {
     if (e.persisted) { // 浏览器后退的时候重新计算
       clearTimeout(tid);
       tid = setTimeout(refreshRem, 300);
     }
  }, false);

  if (doc.readyState === "complete") {
     doc.body.style.fontSize = "16px";
  } else {
     doc.addEventListener("DOMContentLoaded", function(e) {
         doc.body.style.fontSize = "16px";
     }, false);
  }
})(750, 750);   //第一个参数是设计宽度一般宽度有375,640,750根据设计而定,第二个参数是最大宽度推荐设置750或者640都行

 

模板及初始化代码:

html:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no" name="viewport">
<meta content="yes" name="apple-mobile-web-app-capable">
<meta content="black" name="apple-mobile-web-app-status-bar-style">
<meta content="telephone=no" name="format-detection">
<meta content="email=no" name="format-detection">
<meta name="description" content="不超过150个字符"/>
<meta name="keywords" content=""/>
<meta content="caibaojian" name="author"/>
<title>前端开发博客</title>
<link rel="stylesheet" href="base.css">
<script type="text/javascript">
//引入该flexible.min.js
!function(e,t){function n(){var n=l.getBoundingClientRect().width;t=t||540,n>t&&(n=t);var i=100*n/e;r.innerHTML="html{font-size:"+i+"px;}"}var i,d=document,o=window,l=d.documentElement,r=document.createElement("style");if(l.firstElementChild)l.firstElementChild.appendChild(r);else{var a=d.createElement("div");a.appendChild(r),d.write(a.innerHTML),a=null}n(),o.addEventListener("resize",function(){clearTimeout(i),i=setTimeout(n,300)},!1),o.addEventListener("pageshow",function(e){e.persisted&&(clearTimeout(i),i=setTimeout(n,300))},!1),"complete"===d.readyState?d.body.style.fontSize="16px":d.addEventListener("DOMContentLoaded",function(e){d.body.style.fontSize="16px"},!1)}(750,750);
</script>
</head>

<body>
<!-- 正文 -->
</body>
</html>

 

 

初始化样式:

base.css

body,dl,dd,ul,ol,h1,h2,h3,h4,h5,h6,pre,form,input,textarea,p,hr,thead,tbody,tfoot,th,td{margin:0;padding:0;}
ul,ol{list-style:none;}
a{text-decoration:none;}
html{-ms-text-size-adjust:none;-webkit-text-size-adjust:none;text-size-adjust:none;}
body{line-height:1.5; font-size:14px;}
body,button,input,select,textarea{font-family:'helvetica neue',tahoma,'hiragino sans gb',stheiti,'wenquanyi micro hei',\5FAE\8F6F\96C5\9ED1,\5B8B\4F53,sans-serif;}
b,strong{font-weight:bold;}
i,em{font-style:normal;}
table{border-collapse:collapse;border-spacing:0;}
table th,table td{border:1px solid #ddd;padding:5px;}
table th{font-weight:inherit;border-bottom-width:2px;border-bottom-color:#ccc;}
img{border:0 none;width:auto\9;max-width:100%;vertical-align:top; height:auto;}
button,input,select,textarea{font-family:inherit;font-size:100%;margin:0;vertical-align:baseline;}
button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer;}
button[disabled],input[disabled]{cursor:default;}
input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0;}
input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;}
input[type="search"]::-webkit-search-decoration{-webkit-appearance:none;}
input:focus{outline:none;}
select[size],select[multiple],select[size][multiple]{border:1px solid #AAA;padding:0;}
article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block;}
audio,canvas,video,progress{display:inline-block;}
body{background:#fff;}
input::-webkit-input-speech-button {display: none}
button,input,textarea{
-webkit-tap-highlight-color: rgba(0,0,0,0);
}

 

提醒:每个人的解决方案都不一样,根据项目而定。

 

caibaojian.com/simple-flexible.html

 

没有标签
首页      前端资源      为移动端rem单位解决方案——flexible.js

随身笔记

为移动端rem单位解决方案——flexible.js
方案一: 在所有的css和js最先引入 flexible_css.js,flexible  有样式版本 flexible   无样式版本 http://g.tbcdn.cn/mtb/lib-flexible/0.3.4/??flexible_css.js,flexible.js …
扫描二维码继续阅读
2019-04-22