rem的定义和作用,不赘述了。毕竟是n年前就流行起来的方案,目前在pc web和移动端网站都有广泛的应用,下面就贴上笔者整理于网络的两份rem适配方法
偷偷的tips: 侵删哈~
方案一 基于设计稿和制作稿的适配方案
(function(designWidth, maxWidth){
var doc = document,
win = window,
docEl = doc.documentElement,
remStyle = document.createElement("style"), // 创建style标签
tid;
function refreshRem() {
// 设备宽度 (iphone6 设备宽度是375px)
var width = docEl.getBoundingClientRect().width;
maxWidth = maxWidth || 540;
width>maxWidth && (width=maxWidth);
var rem = width * 100 / designWidth; // 各个设备下rem的大小。
remStyle.innerHTML = `html{font-size: ${rem}px;}`;
}
if(docEl.firstElementChild) { // 如果html文档里有元素
docEl.firstElementChild.appendChild(remStyle); // 将style标签写入文档的第一个元素中
} else { // 如果没有就创建一个
var wrap = doc.createElement("div");
wrap.appendChild(remStyle);
doc.write(wrap.innerHTML);
wrap = null;
}
// 要等 viewport 设置好之后才能执行 refreshRem, 不然 refreshRem 会执行2次;
refreshRem();
win.addEventListener("resize",function(){
clearTimeout(tid); // 防止上次执行进程未结束 导致refreshRem 执行两次
tid = setTimeout(refreshRem, 300);
}, false);
win.addEventListener("pageshow", function(e){
if(e.parsisted) { // 浏览器后退时重新计算
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)
desighWidth: 设计稿的实际宽度,根据实际设置
maxWidth: 制作稿的最大宽度值,需要根据实际设置
例子尾部的750,750是以iPhone6为蓝本进行设计的,在这里 1rem = 50px
所以在计算某px值对应的rem值时,只需将px值除以50即可
上面方法是以设计图为制作蓝本,故设置rem的条件变量较为固定
方案二 根据屏幕实际宽度来适配rem的方案
(function(doc,win) {
var docEl = doc,documentElement,
resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
recalc = function () {
var clientWidth = docEl.clientWidth;
if(!clientWidth) return;
if(clientWidth > 750) clientWidth = 750;
docEl.style.fontSize = `${10 * (clientWidth / 320 )}px`;
}
if(!doc.addEventListener) return;
win.addEventListener(resizeEvt, recalc, false);
doc.addEventListener('DOMContentLoaded', recalc, false);
})(document,window)
上面方法是根据访问设备实际宽度来动态设置rem的比例值的
该方案据说是淘宝的h5 rem适配方法, 个人感觉还挺好用的
这里的值 1rem === 11.765px
即用设计图的px值 / 11.765 得到的就是对应位置的rem值
orientationchange: 设备方向改变事件
笔者认为resize的监听优先级低于orientationchange
over。