一、flexiblejs原理
flexiblejs是一款基於淘寶移動端適配方案的自適應方案,在移動端設備中,通過重新計算文檔的根節點字體大小,實現了不同屏幕尺寸下的頁面自適應。
具體來說,它通過以下幾個步驟來實現自適應:
- 獲取設備的屏幕寬度,並計算出font-size的大小。
- 設置viewport的meta標籤。
- 設置根字體大小。
(function(win, lib) {
var timer,
doc = win.document,
docElem = doc.documentElement,
vpMeta = doc.querySelector('meta[name="viewport"]'),
flexMeta = doc.querySelector('meta[name="flexible"]'),
dpr = 0,
scale = 0,
tid;
// 獲取設備CSS像素比
if (vpMeta) {
console.warn('將根據已有的meta標籤來設置縮放比例');
var initial = vpMeta.getAttribute('content').match(/initial\-scale=([\d\.]+)/);
if (initial) {
scale = parseFloat(initial[1]);
dpr = parseInt(1 / scale);
}
}
// 獲取flexible配置信息
if (flexMeta) {
var flex = flexMeta.getAttribute('content');
if (flex) {
var arr = flex.split(';');
for (var i = 0; i max) {
dpr = max;
scale = parseFloat((1 / dpr).toFixed(2));
}
break;
case 'design-width':
lib.designWidth = parseFloat(item[1]);
break;
case 'maxWidth':
lib.maxWidth = parseFloat(item[1]);
break;
case 'disableScale':
lib.disableScale = item[1] === 'true';
break;
}
}
}
}
}
// 設置data-dpr屬性,方便調試
docElem.setAttribute('data-dpr', dpr);
// 設置viewport
if (!vpMeta) {
vpMeta = doc.createElement('meta');
vpMeta.setAttribute('name', 'viewport');
vpMeta.setAttribute('content', 'width=device-width, initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');
if (docElem.firstElementChild) {
docElem.firstElementChild.appendChild(vpMeta);
} else {
var div = doc.createElement('div');
div.appendChild(vpMeta);
doc.write(div.innerHTML);
}
} else {
vpMeta.setAttribute('content', 'width=device-width, initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');
}
// 設置根字體大小
function refreshRem() {
var width = docElem.getBoundingClientRect().width;
if (lib.maxWidth && (width / dpr > lib.maxWidth)) {
width = lib.maxWidth * dpr;
}
var rem = width / 10;
docElem.style.fontSize = rem + 'px';
lib.rem = win.rem = rem;
}
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);
refreshRem();
lib.dpr = win.dpr = dpr;
lib.refreshRem = refreshRem;
lib.rem2px = function(d) {
var val = parseFloat(d) * this.rem;
if (typeof d === 'string' && d.match(/rem$/)) {
val += 'px';
}
return val;
};
lib.px2rem = function(d) {
var val = parseFloat(d) / this.rem;
if (typeof d === 'string' && d.match(/px$/)) {
val += 'rem';
}
return val;
};
})(window, window['lib'] || (window['lib'] = {}));
vpMeta.setAttribute('content', 'width=device-width, initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');
docElem.style.fontSize = rem + 'px';
二、flexiblejs還有人用嗎
隨着CSS3的普及,越來越多的開發者開始使用CSS3的媒體查詢來實現移動端適配。不過,flexiblejs依然是一款優秀的適配方案,尤其適用於需要兼容舊設備的場景。它的優點包括:
- 無需在每個頁面都進行像素單位的轉換,大大提高了開發效率。
- 支持多種分辨率的設備,頁面表現更加一致。
- 支持rem和px單位的自由切換。
- 靈活,可以根據需求進行定製。
三、flexiblejs引入
在引入flexiblejs之前,需要在head區域加入viewport的meta標籤,並去除默認的縮放限制。
然後,在任意一個JS文件中添加以下代碼即可:
(function(win, lib) {
// ...
})(window, window['lib'] || (window['lib'] = {}));
四、flexiblejs不用了
在使用flexiblejs的過程中,我們也要注意一些需要避免的坑,比如:
- 盡量避免使用圖片和視頻等非常大的元素。
- 避免使用過多的字體樣式。
- 盡量遵循設計規範,避免過多使用寬度百分比。
- 不要在樣式表中使用!important,這樣會破壞原本的比例關係。
如果你已經要廢棄flexiblejs,可以單獨在head區域刪除相關的meta標籤,然後手動設置根字體大小即可。
html {
font-size: 16px;
}
五、flexiblejs的缺點
雖然flexiblejs是一款非常優秀的移動端適配方案,但也有一些缺點:
- 有時候會出現模糊的問題。
- 使用rem作為單位,在某些場景下會顯得不夠靈活。
- 對於在Android4.4以下的系統上,可能會遇到一些兼容性問題。
六、flexiblejs替代方案選取
除了flexiblejs以外,還有一些其他的移動端適配方案,比如:
- 媒體查詢:這是最傳統的適配方案,通過CSS3的媒體查詢來適配不同尺寸的設備。
- Bootstrap:這是一款非常流行的響應式框架,可以支持更豐富的頁面布局效果。
- Viewport units:除了rem以外,還可以使用vw和vh等單位來實現自適應。
綜合性能、兼容性和使用難度等因素,可以按照不同項目的需要來選擇適當的方案。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/270044.html
微信掃一掃
支付寶掃一掃