通过纯js代码实现rem自适应布局(移动端、PC端均可)
使用方法:
在html文件内引入此rem.js文件,将单位px按比例换算为rem即可。
注:换算时注意,若UI是按满屏宽度750px出的图,则150px换算为rem就是150/75=2rem(这里为什么除以75是由代码注释2里会指出)。
代码:
// rem.js
(function(win) {
var doc = win.document;
var docEl = doc.documentElement;
var tid;
function refreshRem() {
var width = docEl.getBoundingClientRect().width; //注释1
var rem = width / 10; //注释2
docEl.style.fontSize = rem + 'px';
document.getElementsByTagName("html")[0].style.cssText = 'font-size: ' + rem +"px";
if(parseInt(rem) != parseInt(getComputedStyle(document.getElementsByTagName("html")[0]).fontSize)){ //注释3
var remtrue = rem*(rem/parseInt(getComputedStyle(document.getElementsByTagName("html")[0]).fontSize));
docEl.style.fontSize = remtrue + 'px';
document.getElementsByTagName("html")[0].style.cssText = 'font-size: ' + remtrue +"px";
}
}
win.addEventListener('resize', function() { //注释4
clearTimeout(tid);
tid = setTimeout(refreshRem, 300);
}, false);
win.addEventListener('pageshow', function(e) { //注释5
if (e.persisted) {
clearTimeout(tid);
tid = setTimeout(refreshRem, 300);
}
}, false);
refreshRem();
document.addEventListener('DOMContentLoaded', refreshRem, false); //注释6
})(window);
注释:
-
注释1:object.getBoundingClientRect(); 返回一个 DOMRect 对象(如下图所示),width、height为该DOM的宽高,left、top、x、y为该DOM左上角相对于视图窗口的左上角的距离,right、bottom为该DOM右下角相对于视图窗口的左上角的距离。(此处仅用来获取宽度,可当作拓展知识掌握)
-
注释2:这里是换算rem时为什么除以75的原因,这里将html的fontSize设置为width/10,即1rem等于整屏宽的10%,所以150px占750px几个百分之10就是几rem,即150/(750*0.1)=150/75=2rem。
-
注释3:这里的 if 判断是为了防止用户调节手机本身字号大小,导致我们项目样式错乱问题。(原理:修改手机字号后,
getComputedStyle(document.getElementsByTagName("html")[0]).fontSize
拿到的html的fontSize与原rem不等,通过换算比例,将rem调整即可保证样式不错乱;自然这样通过手机改字号也就失去了作用,可根据需求选择是否添加) -
注释4:给window添加resize监听事件,当window宽高发生变化时会及时更新rem值达到自适应效果。
-
注释5:pageshow事件由前进/后退按钮以及load事件触发后引起。
-
注释6:DOMContentLoaded事件是当document被完整的解析和读取后触发。