初次接觸移動端的時候,以為終於可以不用像pc那樣考慮令人頭疼的ie瀏覽器兼容問題,有強大的css3的幫助,可以隨心所欲。。可是后來才發現原來移動端各種層次不齊的終端更會讓人抓耳撓腮,同樣的頁面在不同的手機上顯示的完全不一樣的效果,於是拋開功能,頁面適配性也成了一個大的課題。
說到移動端,下面這一行代碼大家一定不陌生:
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
如果對viewport還有不理解的可以直接去百度有很多資料,其中,device-width指設備的物理寬度,比如iphone4為320,剩下的initial-scale與maximum-scale指頁面縮放值及最大縮放值,user-scalable表示是否允許縮放。
注意device-width並不等於手機的物理像素,同樣寬度的屏幕物理像素可能為320,640,這就是我們常說的retina屏。當然也就意味着我們css中的1px可能是1個物理像素,也可能是2個物理像素,當然就顯示來說我們設置1px的border不管是在哪個屏幕下看起來都是顯示1px的。
移動端適配的解決方案大概有幾種,現就我所了解的主要方法做個簡單總結:
一.媒體查詢
相信對響應式網站了解的同學都看過下面的寫法:
@media screen and (max-width: 300px){
….
}
通過css3的媒體查詢,我們可以對不同的分辨率設定不同的樣式,如320px(device-width)下字號14px,而375px字號設為16px,等等。
這樣我們就可以做到簡單的適配,不過現在市場機型320,360,375等等各種分辨率,如果我們每一個都去U針對的話,代碼量拋開不說,各種計算也會使得效率極其低下。
二.動態改變縮放值
1 var sW=$(window).width(); 2 3 if(sW>=640&&sW<720){ 4 5 $("#screeMeta").attr("content","width=640, initial-scale=1,minimum-scale=0.5, maximum-scale=0.5"); 6 7 }else if(sW>=720&&sW<750){ 8 9 $("#screeMeta").attr("content","width=640, initial-scale=1,minimum-scale=0.5, maximum-scale=0.56"); 10 11 }else if((sW>=750&&sW<800)){ 12 13 $("#screeMeta").attr("content","width=640, initial-scale=1,minimum-scale=0.5, maximum-scale=0.58"); 14 15 }else if(sW>=800&&sW<1000){ 16 17 $("#screeMeta").attr("content","width=640, initial-scale=1,minimum-scale=0.5, maximum-scale=0.65"); 18 19 }
基本思想為以640為基准,當在標准iphone4的時候頁面整體縮放0.5,然后再遇到不同分辨率的時候賦予不同的縮放值,例如對於device-width為375的情況下,最大縮放值設為375/320*0.5。
這種方法的優點是我們可以完全按照設計稿來設定css尺寸,通過js的計算來實現不同機型的適配。當然缺點就是你當我們嵌入第三方頁面或者將我們的頁面嵌入第三方時,由於縮放值的不同會出現兼容性問題。
三.rem自適應
我們都知道rem不同於em相對於父元素的字體,rem是相對於html根字體來設置的,也就是假設html字體設為16px,那么設置為1rem的元素不論父級元素是哪一層都相當於設置了字體font-size:16px,我們來看一看淘寶和網易的頁面:
iphone4:font-size設為64px,縮放值為0.5
iphone6:font-size設為75px,縮放值為0.5
我們再來看下元素設置:
除字體外,其他單位都用rem,這樣通過動態的計算html的px,頁面內容也會做相應比例的變化,字體用px顯示。當然,他們的理念是大屏就要顯示更多的字體。
關於字體有一個疑問始終沒有搞明白,看下面幾個圖:
data-dpr=1,安卓機,字體設為12px,縮放值為1
data-dpr=2,iphone6,字體設為24px,縮放值為0.5
data-dpr=3,iphone6 plus,字體設為36px,縮放值為0.333
看上面3個截圖,可以看到,通過不同的dpr,為html賦予了不同的data-dpr屬性,然后根據不同的屏幕設置字體屬性和縮放倍數,如1倍屏12px,縮放為1,2倍屏縮放為0.5,3倍屏縮放為0.3333,不清楚這樣做的目的是什么,貌似縮放乘以倍數是一樣的效果,也就是可以用一種設置來實現,不知道理解的是不是有問題?忘大神告知。
關於淘寶h5兼容,這里有詳細的介紹。使用Flexible實現手淘H5頁面的終端適配
下面來看下網易的適配:
安卓1倍屏,device-width為384,html字體設置為51.2
iphone2倍屏,device-width為320,html字體設置為42
iphone3倍屏,device-width為414,html字體設置為55px
網易的縮放值始終為1,而且所有屬性包括字號都是用rem來設置,不同於淘寶,網易客戶端在各種終端顯示內容始終是一致的,這和我們上面講過的動態改變縮放值是一樣的。選定一種寬度為標准,然后其他機型的設置即為標准機型*比例值。
至少就個人來說,我更喜歡網易的這種適配方案,這樣可以保證我的頁面在每個機型上都是一樣的效果。
通過分析上面的幾種方法,我們可以簡單寫一個方法,當然下面方法還沒有經過大量測試,只講方法,慎用
1 function autoSize(width){ 2 3 //如果我們設計稿為750,則傳入750,否則都認為是640 4 var width=width?width:640; 5 6 //為了便於計算,在參照寬度下設html字號為100px, 7 8 var units=width/100; 9 var width=document.documentElement.clientWidth; 10 width=width>1080?1080:width; //設定最大值 11 width=width<=240?240:width; //設定最小值 12 var calFontSize=width/units; //計算html字體的字號 13 14 document.documentElement.style.fontSize=calFontSize+'px'; 15 } 16 autoSize(); 17 window.onresize=function(){ 18 autoSize() 19 }