flexible.js 是手淘的布局适配库

前置的一些概念,能够看这两个文章:
应用Flexible实现手淘H5页面的终端适配
flexible 详解

因为之前接触了很多适配计划,大同小异,导致对rem适配计划始终无奈造成无效的记忆。
这次,间接拿手淘的flexiable 作为规范计划,了解它,作为本人的适配计划。

看flexible要害代码:

找到一个设施的dpr

// 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下,对于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 {            // 其余设施下,仍旧应用1倍的计划            dpr = 1;        }        scale = 1 / dpr;    }

devicePixelRatio

该 Window 属性 devicePixelRatio 可能返回以后显示设施的物理像素分辨率与 CSS 像素分辨率的比率。此值也能够解释为像素大小的比率:
一个 CSS 像素的大小与一个物理像素的大小的比值。简略地说,这通知浏览器应该应用多少个屏幕的理论像素来绘制单个 CSS 像素。

找到一个设施的css宽度(逻辑宽度,视口)

var width = docEl.getBoundingClientRect().width;

getBoundingClientRect

Element.getBoundingClientRect() 办法返回元素的大小及其绝对于视口的地位。
如果是规范盒子模型,元素的尺寸等于width/height + padding + border-width
如果box-sizing: border-box,元素的的尺寸等于 width/height

找到一个设施的 rem

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;    }

width / dpr
失去 1 个 dpr 的物理像素
540
限定,540*dpr 是最大的适配宽度,防止图片含糊;
var rem = width / 10;
把屏幕宽度 分为 10 份,1份1rem;(间接分100份,有1rem 小于12px 的危险)

设计约定俗成的一个前提

设计师个别都是以iphone6 为根底设计UI,iphone6 css width 是375px;设计稿为两倍图 750px;
(设计师为了出高清图,个别稿子都会出到合乎物理像素的大小)

开发一份基于iphone6的UI布局实现

如果设计稿上有个div ,测量是 100*100
因为设计稿总宽度是750px, 分为10分, 每份就是1rem,即是75px; 100/75 = 1.3333 rem
代码就是:

div{    width: 1.3333rem;    height: 1.3333rem;}

这是间接通过rem单位实现了设计稿的尺寸。如果间接放到iphone6 上,会发现,页面比屏幕大了一倍;因为设计稿是依照逻辑像素1:1出的,此时 1px = 1pt。而iphone6 的css是 1px = 2pt 所以咱们还须要对页面缩放 scale

找到一个设施的 scale ,屏幕缩放比

dpr = window.devicePixelRatio
dpr = 物理像素 / 逻辑像素

scale = 1 / dpr;   <meta name='viewport'     content=`    initial-scale=${scale}    minimum-scale=${scale}    maximum-scale=${scale}    user-scalable=no    `     >

所有设施的设计稿实现都放大为 1个逻辑像素屏幕 大小;
这时候,UI 能够在iphone6 的屏幕上完满出现;

其它机型怎么适配?

你曾经失去一份基于iphone6 的 rem 单位实现;
因为rem 是绝对单位,并且是约定把1屏宽度分为10份来实现的rem;换句话说就是,所有1rem为1屏的十分之一的手机,显示这套实现都不会布局错乱。所以这套实现是能够间接复用的。
要复用,须要满足你的html 设置满足一些条件

复用条件

1:把屏幕分为10份,每一份 示意1rem,设置 html: font-size = (width/10) px
2:把视口缩放为 (1/dpr)

大白话

大白话讲,咱们目标是为了 把一份基于rem的实现 放到所有的手机屏幕上,让他们都显示一样,只是等比缩放的差别而已;
通过viewpoint 的 scale 属性,咱们能够把html 像缩放图片一样,缩放到刚刚好100%屏幕。
通过设置1rem 对应十分之一屏幕,咱们能够复用这份布局实现。

后续

因为viewpoint 再浏览器的欠缺,flexible.js 曾经退出2.0版本;后续咱们再做解读
2.0