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。