移動端Wap頁面適配解決方案

web前端開發人員如何才能開發出適配每一個終端的wap頁面呢?若是還有點迷茫不知所措,下面的文章但願可能給你幫助,同時也能夠加深本身的記憶,有欠缺錯誤的地方,歡迎評論指出,相互學習。css

備註:(不討論百分比佈局方式)
      若是有點心急的話能夠直接跳到第5步,欲知其原理還得慢慢來
複製代碼

首先,在解決問題以前,咱們先了解一下熟悉一些有趣的概念,幫助咱們更深的理解解決辦法哦!html

一、像素前端

什麼是像素?

像素是web頁面佈局的基礎,估計咱們每一個前端開發人員都離不開,那麼到底什麼纔是一個像素呢?可能你們會和我同樣有點質疑,是的平時天天都在寫,可是究竟是指什麼呢?
像素:就是計算機屏幕所能顯示一種特定顏色的最小區域。
在web前端開發領域,像素有如下兩種含義:
 一、設備像素(物理像素):設備屏幕的物理像素,對於任何設備來說物理像素的數量是固定不變的。
 二、設備獨立像素(也稱密度無關像素,虛擬像素):能夠認爲是計算機座標系統中的一個點,這個點表明一個能夠由程序使用的虛擬像素(好比說CSS像素),而後由相關係統轉換爲物理像素。
    CSS像素(虛擬像素):這是一個抽象的像素概念,它是爲web開發者創造的。
複製代碼
設備 年份 尺寸 像素 點數
iPhone4S 2011年 3.5 640*960 320*480
iPhone5S 2013年 4.0 640*1136 320*568
iPhone6 2014年 4.7 750*1334 375*667
iPhone6S Plus 2015年 5.5 1242*2208 414*736

備註:此表所列舉的像素即爲設備像素(物理像素)git

二、屏幕密度github

指一個設備表面上存在的像素數量,它一般以每英寸有多少像素來計算(PPI)。
複製代碼

三、設備像素比web

簡稱爲dpr,其定義了物理像素和設備獨立像素的對應關係。它的值能夠按下面的公式計算獲得:
設備像素比(DPR) = 設備像素個數 / 理想視口CSS像素個數(device-width)
在JavaScript中,能夠經過 window.devicePixelRatio 獲取到當前設備的dpr
複製代碼

舉例:iPhone6的設備寬度和高度爲375pt * 667pt,能夠理解爲設備的獨立像素;而其dpr爲2(window.devicePixelRatio ),根據上面公式,咱們能夠很輕鬆得知其物理像素(設備像素)爲750pt * 1334pt。瀏覽器

四、視口(viewport)app

佈局視口:移動端CSS佈局的依據視口,即CSS佈局會根據佈局視口來計算

能夠經過如下JavaScript代碼獲取佈局視口的寬度和高度:

document.documentElement.clientWidth; 
document.documentElement.clientHeight;

可視視口:用戶正在看到網站的區域

理想視口:定義了理想視口的寬度,好比對於iphone6來說,理想視口是375*667。
可是最終做用的仍是佈局視口,由於咱們的css是依據佈局視口計算的,
因此你能夠這樣理解理想視口:理想的佈局視口。
下面這段代碼能夠告訴手機瀏覽器要把佈局視口設爲理想視口:

<meta name="viewport" content="width=device-width" />
複製代碼


打起精神咯,講了這麼多開始進入正題咯...此時能夠來一條華麗的風格線iphone

五、基本定義瞭解以後開始寫代碼了,邊寫代碼邊打開調試模式,對照看可能理解更深入。以iPhone6設備爲例子(若是下面出現的術語有疑問能夠返回來繼續瀏覽)佈局

立刻開始解決問題嘍!

前情概要:iPhone6的設備寬度和高度爲375pt * 667pt,能夠理解爲設備的獨立像素;
而其dpr爲2,根據上面公式,咱們能夠很輕鬆得知其物理像素(設備像素)爲750pt * 1334pt。
複製代碼

a、建立HTML頁面,

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>適配移動終端</title>
<style>
  /* 初始化樣式 */
  *{padding: 0;margin: 0}
  .box{width: 375px;height: 375px;background: blanchedalmond}
</style>
</head>
<body>
  <div class="box"></div>
<script>
  window.onload = function () {
        const screenWidth = document.body.clientWidth;
        console.log("window.devicePixelRatio "+window.devicePixelRatio);
        console.log("document.body.clientWidth的值爲 " + screenWidth);
  }
</script>
</body>
</html>
複製代碼

打開調試器,查看設備像素比=2;佈局視口的寬度=980px

2.png

查看body的寬度:980px,爲佈局視口的寬度

3.png

查看box元素的寬度:375px

4.png

此時,爲了讓box元素的寬度佔滿屏幕,咱們須要將box的寬度設置爲多少呢?本身能夠動手操做一下 . . . . ...

最後.box{width:980px;height:980px},以下圖所示

6.png

緣由:
980px是佈局視口,經過document.documentElement.clientWidth得到,
而咱們平時寫的css樣式則是相對於佈局視口操做的,
因此,可是當佈局視口發生變化的時候咱們須要手動改頁面中元素的尺寸,
複製代碼

那麼有沒有簡單的辦法呢或者可優化的地方呢?

繼續:

b、在該HTML頁面中加入

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
複製代碼

這行代碼你們必定很熟悉,移動端開發通常都要加,加入這行代碼的意思是什麼呢?可讓佈局視口的寬度等於理想視口的寬度,頁面的初始縮放比例以及最大縮放比例都爲1,且不容許用戶對頁面進行縮放操做

7.png

這樣佈局視口和設備的寬度同樣了,都是375px;可是頁面元素box上一步設置的大小是980px因此已經超出了當前屏幕出現了滾動條,要讓該元素全屏顯示須要修改box樣式將寬度改爲375px; 可是仍是同樣的問題,當設備變成了一下設備甚至更多,以下:

設備 設備寬度
iPhone5S 320*568
iPhone6 375*667
iPhone6S Plus 414*736
... ...

還有不少的安卓手機

寬度仍是會改變,應該繼續作些什麼呢?

叮咚!接着就要給你們推薦一個牛通常的存在移動端適配flexible方案

8.png

下載連接中的js,同時引入到咱們的HTML頁面中。 看看是否是解決問題了,無論在iPhone五、iPhone六、iPhone6S Plus...各類設備下.box{width:10rem}都能讓該元素寬度顯示全屏幕,那這個JS到底作了些什麼操做呢?

在這裏先要插播一個單位rem,相信你們都很熟悉, rem 是相對於根元素<html>的font-size來作計算。
而在這個方案中使用rem單位,是能輕易的根據<html>的font-size計算出元素的盒模型大小。
複製代碼

那麼應該怎樣換算成rem呢?

上圖中:根元素HTML字體大小爲37.5px

那麼在該實例中 1rem = 37.5px

同理:

若是根元素HTML字體大小爲75px

那麼在該實例中 1rem = 75px

那麼若是一個頁面根元素(html)字體大小設置爲41.4px,那麼該頁面中有一個元素寬度是270px,轉化成rem是多少呢?

1rem = 41.4px

270px / 41.4px = 6.52rem(約等於)

移動端適配flexible方案主要作了些什麼呢?

目的:適配移動終端 當咱們將頁面的字體設置爲 佈局視口/10的時候,想要讓一個元素全屏顯示寬度,就都是設置10rem

下面咱們來本身算一下:

設置 佈局視口 根目錄字體 大小 頁面中某元素寬度100%
iphone5 320px 32px 1rem = 32px 320px/32px = 10rem
iphone6 375px 37.5px 1rem = 37.5px 375px/37.5px = 10rem
iphone6Ps 414px 41.4px 1rem = 41.4px 414px/41.4px = 10rem
... ... ... ...
解析:佈局視口 (375px)/ 根元素字體大小(37.5px) = 10rem
複製代碼

附上flexible.js(細細品味)

(function flexible (window, document) {
      var docEl = document.documentElement
      var dpr = window.devicePixelRatio || 1

     // adjust body font size
    function setBodyFontSize () {
           if (document.body) {
               document.body.style.fontSize = (12 * dpr) + 'px'
               }
          else {
              document.addEventListener('DOMContentLoaded', 
              setBodyFontSize)
             }
             }
            setBodyFontSize();

           // set 1rem = viewWidth / 10
          function setRemUnit () {
           var rem = docEl.clientWidth / 10
           docEl.style.fontSize = rem + 'px'
           }

           setRemUnit()

           // reset rem unit on page resize
          window.addEventListener('resize', setRemUnit)
          window.addEventListener('pageshow', function (e) {
                  if (e.persisted) {
                        setRemUnit()
                      }
                    })

                    // detect 0.5px supports
          if (dpr >= 2) {
              var fakeBody = document.createElement('body')
              var testElement = document.createElement('div')
              testElement.style.border = '.5px solid transparent'
              fakeBody.appendChild(testElement)
              docEl.appendChild(fakeBody)
          if (testElement.offsetHeight === 1) {
             docEl.classList.add('hairlines')
               }
             docEl.removeChild(fakeBody)
               }
            }(window, document))
複製代碼

但願你能夠本身作一個實例,畢竟書上得來終覺淺,絕知此事要躬行(對某個元素疑問的能夠返回去本身看或者搜索更多的內容,幫助理解)。

你能夠找個現有的PSD設計圖開始練習,尺寸爲750px*1300px(其實和PSD的大小是沒有關係的)

將PSD的尺寸當成佈局視口就能夠了,固然根元素字體就是佈局視口尺寸/10
複製代碼

怎麼樣了?加油,你是最棒的,其實解決這個不僅是這種辦法,你們能夠在理解都基礎上開始各類嘗試,好比根據dpr的值改變佈局視口的大小等等...

總結:其實下載移動端適配flexible方案的js,引入js就能夠解決適配問題,前面囉囉嗦嗦的只是爲了清楚爲何這樣作能夠解決問題,但願能有所幫助。本身理解可能也有些偏差,不足之處望指正。

(參考連接:github.com/amfe/articl…

相關文章
相關標籤/搜索