手淘H5移動端適配方案flexible原始碼分析

2022-03-05 21:13:08 字數 4222 閱讀 2072

移動端適配一直是乙個值得**的問題,在業餘時間我找了一些頁面,檢視了一些廠商對於移動端h5頁面的適配方案,看到了幾個典型的例子,今天就來記錄一下我看到的第乙個典型的例子,也是我們公司目前普通h5專案正在使用的適配方案。

這個適配方案是lib-flexible,在看這個原始碼的同時,我想先來回顧一下幾個概念:

1.  viewport

<

mate

name

="viewport"

content

="width=device-width,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,user-scalable=no"

/>

上面這行**的作用是讓當前viewport的寬度等於裝置寬度,頁面初始縮放比例為1,viewport最大的縮放比例為1,viewport最小的縮放比例也為1,同時不允許使用者拖動縮放。

屬性

作用值型別

width

規定頁面的寬度

可以為字串值"device-width",或者正整數

initial-scale

規定頁面的初始縮放比例

為數字,可以為小數

maximum-scale

規定頁面的最大縮放比例

為數字,可以為小數

minimum-scale

規定頁面的最小縮放比例

為數字,可以為小數

user-scalable

規定是否允許使用者進行拖動縮放

yes或no,yes是允許,no則不允許

好了,先熟悉到這裡,後面如果想對viewport有更深入透徹的研究,可以檢視ppk大神的關於viewport的三篇文章。

2.裝置畫素比

關於裝置畫素比,我們先賣個關子,後面會說。我們先來看一下另乙個值得思考的問題,我們css中常用的單位px到底和我們移動裝置螢幕上的畫素(pixel)是什麼關係?css裡的1px等於移動裝置螢幕上的1畫素嗎?

首先,我來繞一波,px確實是英文畫素(pixel)的縮寫;但是!!!我們這裡為了將css中的px和裝置中的物理畫素加以區分,css中的單位描述我們就用熟悉的px,裝置的物理畫素,我們則用pixel來加以區分!!!

那麼問題來了,我css中的1px到底等於裝置物理畫素1pixel嗎?----答案是:不一定!!!

那麼為什麼是不一定呢?這裡我們又要了解兩個相關概念:

(1)物理畫素:裝置的物理畫素,顧名思義就是乙個移動裝置在出廠時就固定了的畫素,整個螢幕是由乙個挨著乙個間隙極小的畫素組成的,是螢幕顯示中的基本單元,例如某款手機螢幕解析度:1920*1080畫素,這裡所說的1920就是該款手機螢幕縱向的畫素排布數量,1080就是橫向畫素排布數量,這裡的畫素就是我們所說的物理畫素pixel。

(2)獨立畫素:獨立畫素也可以稱之為邏輯畫素,乙個邏輯畫素是螢幕接受程式控制的最小單位,簡言之我們可以將這裡的邏輯畫素和我們css中的px建立起聯絡,即css中的1px可以控制1個邏輯畫素的顯示。

書接前文,前面提到我們css中的1px不一定等於我們裝置的物理畫素1pixel,那麼什麼情況下等於?什麼情況下又不等於?

等於的情況:早在移動端視網膜螢幕上市以前,絕大部分手機的物理畫素和邏輯畫素其實是對等的,比如iphone 3 的手機螢幕(物理畫素:320x480;邏輯畫素:320x480)。這裡就是css 中的1px等於移動裝置的物理畫素1pixel。也就是說此時,物理畫素÷邏輯畫素=1,這個比值就是裝置畫素比(dpr)。

不等於的情況:當 iphone 4 手機問世時,掀起了視網膜平螢幕的浪潮,以iphone 4 手機螢幕為例(物理畫素:640x960;邏輯畫素:320x480),由此可見iphone 4  相比於iphone 3 的手機螢幕,物理畫素多了一倍,但是邏輯畫素卻沒有變化,那麼iphone 4 的裝置畫素比: 物理畫素÷邏輯畫素=2,也就是說  dpr=2 。當然,隨著手機日新月異的發展,dpr=3的情況也是有的,例如總結的下表各主要手機型號的裝置畫素比:

手機型號

物理畫素

獨立畫素(邏輯畫素)

dpr倍圖

iphone  5/5s/5e

640*1136

320*568

2@2x

iphone 6/7/8

750*1334

375*667

2@2x

iphone 6p/7p/8p

1242*2208

414*736

3@3x

手機型號

物理畫素

邏輯畫素

dpr倍圖

android 1

320*480

320*480

1@1x

android 2

540*960

360*640

[email protected]

android 3

640*960

320*480

2@2x

android 4

720*1280

360*640

2@2x

android 5

1080*1920

360*640

3@3x

好了,巴拉了這麼多,該切入正題上lib-flexible原始碼了,如下:

;(function

(win, lib) );

if(metael)

} else

if(flexibleel)

if(maximumdpr) }}

if (!dpr && !scale)

else

if (devicepixelratio >= 2 && (!dpr || dpr >= 2))

else

} else

scale = 1 /dpr;

}docel.setattribute('data-dpr', dpr); // 給頁面根元素設定自定義屬性data-dpr,值為前面已經賦值好的dpr

if (!metael)

else

}function

refreshrem()

var rem = width / 10; // 將螢幕寬度分成10份,每乙份為1rem 所以整個螢幕的完整寬度為10rem

docel.style.fontsize = rem + 'px'; // 設定根元素字型大小為計算所得的值

flexible.rem = win.rem =rem;

}win.addeventlistener('resize', function

() ,

false

); win.addeventlistener('pageshow', function

(e)

}, false

);

if (doc.readystate === 'complete')

else

, false

); }

refreshrem();

// 後面這段**是將rem單位值轉換成px的和將px單位的值換算成rem單位的值

flexible.dpr = win.dpr =dpr;

flexible.refreshrem =refreshrem;

flexible.rem2px = function

(d)

return

val;

}flexible.px2rem = function

(d)

return

val;

}})(window, window['lib'] || (window['lib'] = {}));

原始碼的分析已經注釋到**後面的注釋中了。通過原始碼的整體分析,我們會發現,lib-flexible的工作原理可以概括為:

通過獲取裝置畫素比dpr進行運算,設定頁面裡name=viewport的mate標籤(包括內部的縮放比例),再在頁面根元素--html上新增data-dpr屬性以及值,並且設定根元素字型大小,來進行頁面適配的。

隨著技術的飛速發展,當前lib-flexible適配方案也在逐漸被更新的適配方案所替代,但是截止目前為止,還沒有發現哪種方案能完全滿足適配各種機型的需要,也會有一些小的問題。lib-flexible是目前用到的比較成熟的適配方案,所以,讓我們一起繼續探索吧~

h5移動端適配方案

flex布局 flex布局,不使用rem,直接使用px。doctype html html head title title style 利用flex屬性,可以實現塊級元素1 1 1 簡單的就能使裡面的內容居中 尤其是垂直居中,好用到爆 box item1 item2 item3 style hea...

h5移動端適配

原理 postcss function 視覺稿的1 10 在index.html中指定 font size為document寬度的1 10 iphonex 的解析度 2436 1125 pt 812 375 dpr 3 iphonexr的解析度 1792 828 pt 896 414 dpr 3 i...

H5移動端適配總結

因此通過查閱資料,了解到兩種螢幕適配的方案 1.通過對介面進行等比例縮放 2.使用rem單位進行介面的適配。1 第一種方式屬於有一種暴力適配,即通過計算設計人員給出的設計稿的尺寸和裝置的真實尺寸,將這個比值作為縮放比賦值飛meta標籤,但是這種情況下往往會出現字型和的失真或者銳化。實現 大致如下 以...