日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

移动端适配--flexible.js

發(fā)布時(shí)間:2024/9/21 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 移动端适配--flexible.js 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

引言:

H5適配一直是一個(gè)比較普遍的問(wèn)題,很多文章都會(huì)講,最近開發(fā)了一個(gè)H5的項(xiàng)目使用了一下淘寶的 flexible.js,寫一篇文章自己總結(jié)一下。

一、背景介紹:

Flexible.js是淘寶公開的一種移動(dòng)端適配方案,用來(lái)解決H5開發(fā)中的各個(gè)機(jī)型適配問(wèn)題,是一種比較成熟的適配方案。

二、使用方法:

在html頭部引入flexible.js,最好放在最頭部,重構(gòu)時(shí)使用rem替代px像素即可,flexible會(huì)做好所有適配。換算關(guān)系為1rem對(duì)應(yīng)1/10設(shè)計(jì)尺寸,如ipone6設(shè)計(jì)尺寸為750px,那么重構(gòu)時(shí)寬度對(duì)應(yīng)的就是10rem。

<script type="text/javascript" src="../../js/flexible.js"></script>

三、Flexible.js原理:

比較短,直接上代碼:

;(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 = {});if (metaEl) {console.warn('將根據(jù)已有的meta標(biāo)簽來(lái)設(shè)置縮放比例');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)); }}}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下,對(duì)于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 {var wrap = doc.createElement('div');wrap.appendChild(metaEl);doc.write(wrap.innerHTML);}}function refreshRem(){var width = docEl.getBoundingClientRect().width;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();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'] = {}));

可以看出其核心就是兩段代碼:

1.當(dāng)用戶沒有設(shè)置viewport的時(shí)候調(diào)整viewport:

metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');

viewport(視口)的調(diào)整邏輯是根據(jù)dpr(window.devicePixelRatio,設(shè)備像素比)來(lái)調(diào)整。

以iphone6為例:

dpr = 2,sale = 1/dpr = 0.5,也是就是說(shuō)flexible會(huì)將視口縮放到原來(lái)的0.5倍,這樣做的好處是能讓邏輯像素與物理像素相等,避免出現(xiàn)1px在retina屏幕上顯示過(guò)粗的現(xiàn)象(移動(dòng)端經(jīng)典的1px問(wèn)題)。

2.設(shè)置根元素字體大小:

function refreshRem(){var width = docEl.getBoundingClientRect().width;if (width / dpr > 540) {width = 540 * dpr;}var rem = width / 10;docEl.style.fontSize = rem + 'px';flexible.rem = win.rem = rem;}

rem是根據(jù)根元素來(lái)做渲染的,所以flexible直接調(diào)整根元素的大小就可以做到適配了,調(diào)整的思路是根據(jù)視口寬度(document.doumentElement.getBoundingClientRect().width)做調(diào)整(ps:viewport還分layout viewport和 visual viewport,不引申)。

四、注意事項(xiàng)&&總結(jié):

1.當(dāng)用戶不設(shè)置viewport的時(shí)候,flexible.js會(huì)根據(jù)dpr默認(rèn)設(shè)置viewport,這里的好處已經(jīng)講到,在精準(zhǔn)顯示1px像素的時(shí)候比較準(zhǔn)確。但是也會(huì)帶來(lái)部分問(wèn)題,如引用第三方插件并且插件本身用px像素設(shè)置,這個(gè)時(shí)候就會(huì)帶來(lái)縮放顯示問(wèn)題,所以如果有這種需求的話建議自己權(quán)衡,個(gè)人建議可能使用第三方的業(yè)務(wù)自行設(shè)置viewport,1px問(wèn)題可以用其他手段處理,一般沒有高保真的需求本身也沒有必要。

2.flexible對(duì)字體的設(shè)置不推薦使用rem單位,建議使用px像素,適配根據(jù)dpr來(lái)做。原因簡(jiǎn)單看了下主要是網(wǎng)頁(yè)可能會(huì)使用點(diǎn)陣字體,一般點(diǎn)陣大小是16、24的,調(diào)整后的字體大小可能不大標(biāo)準(zhǔn),在字體點(diǎn)陣上顯示會(huì)比較模糊,不細(xì)究了,有時(shí)間再研究補(bǔ)充。

總結(jié):移動(dòng)端適配核心就是將像素rem化,之后根據(jù)視口調(diào)整根元素達(dá)到適配的效果。

轉(zhuǎn)載于:https://www.cnblogs.com/DevinnZ/p/8683902.html

總結(jié)

以上是生活随笔為你收集整理的移动端适配--flexible.js的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。