1. 首先是適配基礎(chǔ)知識的補(bǔ)充,主要是利用rem
http://caibaojian.com/flexible-js.html
1.2 適配的原理如下
a ) 首先利用flexible.js確定適配基礎(chǔ)dpr和font-size
b ) 然后使用px2rem2-loader實(shí)現(xiàn)px轉(zhuǎn)化為rem的值,(rem的值是由HTML的font-size來確定的) 按照6s設(shè)計圖來配置相關(guān)參數(shù)
2. 然后具體的實(shí)現(xiàn)方案
- 首先將index.html修改如下(flexible.js的內(nèi)容移動到這里了)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
<script lang="javascript">
'use strict';
(function(win, lib) {
let doc = win.document;
let docEl = doc.documentElement;
let metaEl = doc.querySelector('meta[name="viewport"]');
let flexibleEl = doc.querySelector('meta[name="flexible"]');
let dpr = 0;
let scale = 0;
let tid;
let flexible = lib.flexible || (lib.flexible = {});
if (metaEl) {
//console.warn('將根據(jù)已有的meta標(biāo)簽來設(shè)置縮放比例');
let match = metaEl.getAttribute('content').match(/initial-scale=([\d.]+)/);
if (match) {
scale = parseFloat(match[1]);
dpr = parseInt(1 / scale);
}
} else if (flexibleEl) {
let content = flexibleEl.getAttribute('content');
if (content) {
let initialDpr = content.match(/initial-dpr=([\d.]+)/);
let maximumDpr = content.match(/maximum-dpr=([\d.]+)/);
if (initialDpr) {
dpr = parseFloat(initialDpr[1]);
scale = parseFloat((1 / dpr).toFixed(2));
}
if (maximumDpr) {
dpr = parseFloat(maximumDpr[1]);
scale = parseFloat((1 / dpr).toFixed(2));
}
}
}
if (!dpr && !scale) {
let isAndroid = win.navigator.appVersion.match(/android/gi);
let isIPhone = win.navigator.appVersion.match(/iphone/gi);
let devicePixelRatio = win.devicePixelRatio;
if (isIPhone) {
// iOS下,對于2和3的屏,用2倍的方案,其余的用1倍方案
if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {
dpr = 3;
} else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)) {
dpr = 2;
} else {
dpr = 1;
}
} else {
// 其他設(shè)備下,仍舊使用1倍的方案
dpr = 1;
}
scale = 1 / dpr;
}
docEl.setAttribute('data-dpr', dpr);
if (!metaEl) {
metaEl = doc.createElement('meta');
metaEl.setAttribute('name', 'viewport');
metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');
if (docEl.firstElementChild) {
docEl.firstElementChild.appendChild(metaEl);
} else {
let wrap = doc.createElement('p');
wrap.appendChild(metaEl);
doc.write(wrap.innerHTML);
}
}
function refreshRem() {
let width = docEl.getBoundingClientRect().width;
if (width / dpr > 540) {
width = 540 * dpr;
}
let rem = width / 10;
docEl.style.fontSize = rem + 'px';
flexible.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);
if (doc.readyState === 'complete') {
doc.body.style.fontSize = 12 * dpr + 'px';
} else {
doc.addEventListener('DOMContentLoaded',
function(e) {
doc.body.style.fontSize = 12 * dpr + 'px';
},
false);
}
refreshRem();
flexible.dpr = win.dpr = dpr;
flexible.refreshRem = refreshRem;
flexible.rem2px = function(d) {
let val = parseFloat(d) * this.rem;
if (typeof d === 'string' && d.match(/rem$/)) {
val += 'px';
}
return val;
}
flexible.px2rem = function(d) {
let val = parseFloat(d) / this.rem;
if (typeof d === 'string' && d.match(/px$/)) {
val += 'rem';
}
return val;
}
})(window, window['lib'] || (window['lib'] = {}));
</script>
<title>app的標(biāo)題</title>
</head>
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
注:遇到的問題
網(wǎng)上找到很多的博客的內(nèi)容是將flexible.js單獨(dú)的提出去,但是在實(shí)際的操作中發(fā)現(xiàn)會導(dǎo)致在通過瀏覽器的按鈕刷新的時候?qū)е逻m配出現(xiàn)錯誤,所以解決方案就是是把flexible.js的代碼移到了index.html內(nèi)部,沒有采用靜態(tài)鏈接的方式。
知識點(diǎn)補(bǔ)充:flexible.js 主要做了下面的幾件事
動態(tài)改寫<meta>標(biāo)簽
給<html>元素添加data-dpr屬性,并且動態(tài)改寫data-dpr的值
給<html>元素添加font-size屬性,并且動態(tài)改寫font-size的值
- 然后接著按照上面文檔的設(shè)置即可(從4開始配置)https://www.cnblogs.com/xiaobaibubai/p/8528744.html,
這個步驟是為了將px轉(zhuǎn)化為rem。
知識點(diǎn)補(bǔ)充:使用Flexible實(shí)現(xiàn)手淘H5頁面的終端適配
https://github.com/amfe/article/issues/17?utm_source=caibaojian.com