摘要:如何以不變應(yīng)萬變,用簡(jiǎn)簡(jiǎn)單單的幾行代碼就能支持種類繁多的屏幕分辨率呢今天就給大家介紹一種懶人必備的移動(dòng)端定寬網(wǎng)頁(yè)適配方法。測(cè)試設(shè)備三星真機(jī)三星虛擬機(jī)真機(jī)的適配比較簡(jiǎn)單,只需要設(shè)置即可。
本文最初發(fā)布于我的個(gè)人博客:咀嚼之味
如今移動(dòng)設(shè)備的分辨率紛繁復(fù)雜。以前僅僅是安卓機(jī)擁有各種各樣的適配問題,如今 iPhone 也擁有了三種主流的分辨率,而未來的 iPhone 7 可能又會(huì)玩出什么新花樣。如何以不變應(yīng)萬變,用簡(jiǎn)簡(jiǎn)單單的幾行代碼就能支持種類繁多的屏幕分辨率呢?今天就給大家介紹一種懶人必備的移動(dòng)端定寬網(wǎng)頁(yè)適配方法。
首先看看下面這行代碼:
有過移動(dòng)端開發(fā)經(jīng)驗(yàn)的同學(xué)是不是對(duì)上面這句代碼非常熟悉?它可能最常見的響應(yīng)式設(shè)計(jì)的 viewport 設(shè)置之一,而我今天介紹的這種方法也是利用了 meta 標(biāo)簽設(shè)置 viewport 來支持大部分的移動(dòng)端屏幕分辨率。
目標(biāo)僅僅通過配置 使得移動(dòng)端網(wǎng)站只需要按照固定的寬度設(shè)計(jì)并實(shí)現(xiàn),就能在任何主流的移動(dòng)設(shè)備上都能看到符合設(shè)計(jì)稿的頁(yè)面,包括 Android 4+、iPhone 4+。
測(cè)試設(shè)備三星 Note II (Android 4.1.2) - 真機(jī)
三星 Note III (Android 4.4.4 - API 19) - Genymotion 虛擬機(jī)
iPhone 6 (iOS 9.1) - 真機(jī)
iPhoneiPhone 的適配比較簡(jiǎn)單,只需要設(shè)置 width 即可。比如:
這樣你的頁(yè)面在所有的 iPhone 上,無論是 寬 375 像素的 iPhone 6 還是寬 414 像素的 iPhone 6 plus,都能顯示出定寬 320 像素的頁(yè)面。
AndroidAndroid 上的適配被戲稱為移動(dòng)端的 IE,確實(shí)存在著很多兼容性問題。Android 以 4.4 版本為一個(gè)分水嶺,首先說一說相對(duì)好處理的 Android 4.4+
Android 4.4+為了兼容性考慮,Android 4.4 以上拋棄了 target-densitydpi 屬性,它只會(huì)在 Android 設(shè)備上生效。如果對(duì)這個(gè)被廢棄的屬性感興趣,可以看看下面這兩個(gè)鏈接:
Support for target-densitydpi is removed from WebKit
Bug 88047 - Remove support for target-densitydpi in the viewport meta tag
我們可以像在 iPhone 上那樣設(shè)置 width=320 以達(dá)到我們想要的 320px 定寬的頁(yè)面設(shè)計(jì)。
Android 4.0 ~ 4.3
作為 Android 相對(duì)較老的版本,它對(duì) meta 中的 width 屬性支持得比較糟糕。以三星 Note II 為例,它的 device-width 是 360px。如果設(shè)置 viewport 中的 width (以下簡(jiǎn)稱 vWidth ) 為小于等于 360 的值,則不會(huì)有任何作用;而設(shè)置 vWidth 為大于 360 的值,也不會(huì)使畫面產(chǎn)生縮放,而是出現(xiàn)了橫向滾動(dòng)條。
想要對(duì) Android 4.0 ~ 4.3 進(jìn)行支持,還是不得不借助于頁(yè)面縮放,以及那個(gè)被廢除的屬性:target-densitydpi。
target-densitydpitarget-densitydpi 一共有四種取值:low-dpi (0.75), medium-dpi (1.0), high-dpi (1.5), device-dpi。在 Android 4.0+ 的設(shè)備中,device-dpi 一般都是 2.0。我使用手頭上的三星 Note II 設(shè)備 (Android 4.1.2) 進(jìn)行了一系列實(shí)驗(yàn),得到了下面這張表格:
target-densitydpi | viewport: width | body width | 屏幕可視范圍寬度 |
---|---|---|---|
low-dpi (0.75) | vWidth <= 320 | 270 | 270 |
vWidth > 320 | vWidth* | 270 | |
medium-dpi (1.0) | vWidth <= 360 | 360 | 360 |
vWidth > 360 | vWidth* | 360 | |
high-dpi (1.5) | vWidth <= 320 | 540 | 540 |
320 < vWidth <= 540 | vWidth* | vWidth* | |
vWidth > 540 | vWidth* | 540 | |
device-dpi (2.0)** | vWidth <= 320 | 720 | 720 |
320 < vWidth <= 720 | vWidth* | vWidth* | |
vWidth > 720 | vWidth* | 720 |
vWidth*:指的是與 viewport 中設(shè)置的 width 的值相同。
device-dpi (2.0)**:在 Android 4.0+ 的設(shè)備中,device-dpi 一般都是 2.0。
首先可以看到 320px 是個(gè)特別詭異的臨界值,低于這個(gè)臨界值后就會(huì)發(fā)生超出我們預(yù)期的事情。綜合考慮下來,還是采用 target-densitydpi = device-dpi 這一取值。如果你想要以 320px 作為頁(yè)面的寬度的話,我建議你針對(duì)安卓 4.4 以下的版本設(shè)置 width=321。
如果 body 的寬度超過屏幕可視范圍的寬度,就會(huì)出現(xiàn)水平的滾動(dòng)條。這并不是我們期望的結(jié)果,所以我們還要用到縮放屬性 initial-scale。計(jì)算公式如下:
Scale = deviceWidth / vWidth
這樣的計(jì)算式不得不使用 JS 來實(shí)現(xiàn),最終我們就能得到適配 Android 4.0 ~ 4.3 定寬的代碼:
var match, scale, TARGET_WIDTH = 320; if (match = navigator.userAgent.match(/Android (d+.d+)/)) { if (parseFloat(match[1]) < 4.4) { if (TARGET_WIDTH == 320) TARGET_WIDTH++; var scale = window.screen.width / TARGET_WIDTH; document.querySelector("meta[name="viewport"]").setAttribute("content", "width=" + TARGET_WIDTH + ", initial-scale = " + scale + ", target-densitydpi=device-dpi"); } }
其中,TARGET_WIDTH 就是你所期望的寬度,注意這段代碼僅在 320-720px 之間有效哦。
縮放中的坑如果是 iPhone 或者 Android 4.4+ 的機(jī)器,在使用 scale 相關(guān)的屬性時(shí)要非常謹(jǐn)慎,包括 initial-scale, maximum-scale 和 minimum-scale。
要么保證 Scale = deviceWidth / vWidth,要么就盡量不用。來看一個(gè)例子:
在縮放比不能保證的情況下,即使設(shè)置同樣的 width 和 initial-scale 后,兩者的表現(xiàn)也是不一致。具體兩種機(jī)型采用的策略如何我還沒有探索出來,有興趣的同學(xué)可以研究看看。最省事的辦法就是在 iPhone 和 Android 4.4+ 上不設(shè)置 scale 相關(guān)的屬性。
總結(jié)結(jié)合上面所有的分析,你可以通過下面這段 JS 代碼來對(duì)所有 iPhone 和 Android 4+ 的手機(jī)屏幕進(jìn)行適配:
var match, scale, TARGET_WIDTH = 320; if (match = navigator.userAgent.match(/Android (d+.d+)/)) { if (parseFloat(match[1]) < 4.4) { if (TARGET_WIDTH == 320) TARGET_WIDTH++; var scale = window.screen.width / TARGET_WIDTH; document.querySelector("meta[name="viewport"]").setAttribute("content", "width=" + TARGET_WIDTH + ", initial-scale = " + scale + ", target-densitydpi=device-dpi"); } } else { document.querySelector("meta[name="viewport"]").setAttribute("content", "width=" + TARGET_WIDTH); }
如果你不希望你的頁(yè)面被用戶手動(dòng)縮放,你還可以加上 user-scalable=no。不過需要注意的是,這個(gè)屬性在部分安卓機(jī)型上是無效的哦。
其他參考資料Supporting Different Screens in Web Apps - Android Developers
Viewport target-densitydpi support is being deprecated
附錄 - 測(cè)試頁(yè)面有興趣的同學(xué)可以拿這個(gè)測(cè)試頁(yè)面來測(cè)測(cè)自己的手機(jī),別忘了改 viewport 哦。
Document 100px200px300px320px
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/78266.html
摘要:實(shí)戰(zhàn)之微信錢包騰訊服務(wù)界面網(wǎng)格布局是讓開發(fā)人員設(shè)計(jì)一個(gè)網(wǎng)格并將內(nèi)容放在這些網(wǎng)格內(nèi)。對(duì)于移動(dòng)端適配,不同的公司不同的團(tuán)隊(duì)有不同的解決方案。柵格系統(tǒng)用于處理頁(yè)面多終端適配的問題。 grid實(shí)戰(zhàn)之微信錢包 騰訊服務(wù)界面 CSS3網(wǎng)格布局是讓開發(fā)人員設(shè)計(jì)一個(gè)網(wǎng)格并將內(nèi)容放在這些網(wǎng)格內(nèi)。而不是使用浮動(dòng)制作一個(gè)網(wǎng)格,實(shí)際上是你將一個(gè)元素聲明為一個(gè)網(wǎng)格容器,并把元素內(nèi)容置于網(wǎng)格中。 移動(dòng)端頁(yè)面適配—...
摘要:發(fā)布應(yīng)用市場(chǎng)的平臺(tái)搶紅包工具紅包精靈開源啦掘金紅包精靈,如果喜歡,點(diǎn)個(gè)開源不易。作者將原素材文章進(jìn)行了新內(nèi)容的添加和重新排列,但是因?yàn)槲恼赂咝У拇a編寫技巧總結(jié)前端掘金本文總結(jié)了代碼編寫技巧,來提升你的和代碼。 收藏安卓開發(fā)中非常實(shí)用優(yōu)秀的庫(kù)! 有圖有真相! - Android - 掘金本來是打算收藏工具類的,但轉(zhuǎn)念一想,已經(jīng)有這么多優(yōu)秀的庫(kù)了,就沒必要再去重復(fù)造輪子了,便歸納工作中比...
摘要:從事開發(fā)好多年,但是手機(jī)頁(yè)面開發(fā)較晚,所以最開始的時(shí)候,為了做微信應(yīng)用的開發(fā),各種餓補(bǔ),但是為了將設(shè)計(jì)稿精準(zhǔn)的適配在各種尺寸的手機(jī)上還是太坑,所以找了些資料后,借鑒了一些成熟的網(wǎng)站,分享出來,歡迎拍磚。 從事PC Web開發(fā)好多年,但是手機(jī)頁(yè)面開發(fā)較晚,所以最開始的時(shí)候,為了做微信應(yīng)用的開發(fā),各種餓補(bǔ),但是為了將設(shè)計(jì)稿精準(zhǔn)的適配在各種尺寸的手機(jī)上還是太坑,所以找了些資料后,借鑒了一些成...
閱讀 3268·2023-04-25 22:47
閱讀 3779·2021-10-11 10:59
閱讀 2314·2021-09-07 10:12
閱讀 4269·2021-08-11 11:15
閱讀 3440·2019-08-30 13:15
閱讀 1757·2019-08-30 13:00
閱讀 976·2019-08-29 14:02
閱讀 1691·2019-08-26 13:57