版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
这两天回头巩固知识点,才算真正的了解了rem(一直以为就直接用就行,尴尬)
啥是rem
rem是指相对于根元素的字体大小的单位。简单的说它就是一个相对单位。看到rem大家一定会想起em单位,em是指相对于父元素的字体大小的单位。它们之间其实很相似,只不过rem计算的规则是依赖根元素,em是依赖父元素计算。
rem布局原理: 拿到设计稿,按照设计稿的宽去设置一个合适的rem ,配合js查询屏幕大小来改变html的font-size,从而达到适配各种屏幕的效果
rem转换秘籍: 1rem=16px(默认)
rem咋用
首先,你需要加一个“头”,不是让你这个人加,是给程序head里加一个标签,来保证“尺寸的完整”:
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no">
前面说了,网页中默认 1rem=16px ,你可以通过改变根元素px大小来改变字体大小,这同样基于前面的公式,比如:
@media and (max-width: 980px){
html{
font-size: 12px;
}
}
这里,在页面宽度小于等于980px时,有:1rem=12px,字体就变小了。
但真正的“响应式”还是需要通过js来“监控”:
let htmlWidth=document.documentElement.clientWidth || document.body.clientWidth;
let htmlDom=document.getElementsByTagName('html')[0];
htmlDom.style.fontSize=htmlWidth/20+'px'; //这里当然也可以除以15、10...
那么问题又来了:你这样监控的是“窗口宽度”,这需要实时变化,这不是会平白增加DOM树渲染和重绘的时间吗?
怎么解决?
我在这篇文章中提到,我们可以通过 延迟监听频率 来一定程度上缓解这个问题。
var throttle=function (fn,interval) {
var __self=fn, //定义一个私有变量指向传入的函数——方便内部操作
timer,
firstTime=true; //是否是第一次调用
return function () {
var args=arguments, //apply两个参数——一个“修正的”this,一个传入的参数——比如这里argument就是指回调函数的interval操作
__me=this;
if(firstTime){
__self.apply(__me,args); //修正! ——防止回调函数指向错误,用apply把函数的this指向调用的变量(对象)
return firstTime=false;
}
if(timer){
return false; // 节流的宗旨:如果timer存在,就直接退出(不执行第一次timer的相同代码了)
}
timer=setTimeout(function () {
clearTimeout(timer);
timer=null;
__self.apply(__me,args);
},interval||700);
};
};
let htmlWidth=document.documentElement.clientWidth || document.body.clientWidth;
let htmlDom=document.getElementsByTagName('html')[0];
window.onresize=throttle(function () {
htmlDom.style.fontSize=htmlWidth/20+'px';
},700);
700s监听一次,OK!