####淘寶實用lib-flexible來適配各類大小的屏幕,如今來說講適配的原理html
<script src="src/lib-flexible.js"></script>
複製代碼
;(function(win, lib) {
var doc = win.document;
var docEl = doc.documentElement;
var metaEl = doc.querySelector('meta[name="viewport"]');
var flexibleEl = doc.querySelector('meta[name="flexible"]');
var dpr = 0;
var scale = 0;
var tid;
var flexible = lib.flexible || (lib.flexible = {});
/*將根據已有的meta標籤來設置縮放比例*/
if (metaEl) {
var match = metaEl.getAttribute('content').match(/initial\-scale=([\d\.]+)/);
if (match) {
scale = parseFloat(match[1]);
dpr = parseInt(1 / scale);
}
} else if (flexibleEl) {
var content = flexibleEl.getAttribute('content');
if (content) {
var initialDpr = content.match(/initial\-dpr=([\d\.]+)/);
var 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));
}
}
}
/*當原先沒有設置過meta,以及縮放比例
* iphone手機根據2,3屏幕處理
* 其餘設備下,仍舊使用1倍的方案 獲得dpr和scale的值
* */
if (!dpr && !scale) {
var isAndroid = win.navigator.appVersion.match(/android/gi);
var isIPhone = win.navigator.appVersion.match(/iphone/gi);
var 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 {
// 其餘設備下,仍舊使用1倍的方案
dpr = 1;
}
scale = 1 / dpr;
}
/*設置html的data-dpr的值*/
docEl.setAttribute('data-dpr', dpr);
/*
*scale
* 查詢有沒有meta屬性,沒有的狀況下加上 <meta content='initial-scale= scale, maximum-scale=scale, minimum-scale=scale, user-scalable=no/> * */ 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 { var wrap = doc.createElement('div'); wrap.appendChild(metaEl); doc.write(wrap.innerHTML); } } /* * 這個width跟dpr有關係 例如iphone5 dpr爲2 獲得的屏幕的寬爲640px * 例如iphone6 plus dpr爲3 獲得的屏幕的寬爲1242px * */ function refreshRem(){ var width = docEl.getBoundingClientRect().width; //注意這裏,這裏是適配手機的一個具體的參數,相對大於540的就不適用了 if (width / dpr > 540) { width = 540 * dpr; } var 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(); /*rem轉px px轉rem*/ flexible.dpr = win.dpr = dpr; flexible.refreshRem = refreshRem; flexible.rem2px = function(d) { var val = parseFloat(d) * this.rem; if (typeof d === 'string' && d.match(/rem$/)) { val += 'px'; } return val; } flexible.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'] = {})); 複製代碼
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
設備的物理分辨率/(devicePixelRatio * scale),在scale爲1的狀況下,device-width = 設備的物理分辨率/devicePixelRatio 。前端
devicePixelRatio稱爲設備像素比,每款設備的devicePixelRatio都是已知,而且不變的,目前高清屏,廣泛都是2,不過還有更高的,好比2.5, 3 等,我魅族note的手機的devicePixelRatio就是3。淘寶觸屏版佈局的前提就是viewport的scale根據devicePixelRatio動態設置:android
https://github.com/amfe/lib-flexible
####參考 前端開發博客(沒有找到名字的人)git