乐趣区

关于html5:用大白话理解-flexiblejs-10-移动端可伸缩适配方案

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

退出移动版