共计 2200 个字符,预计需要花费 6 分钟才能阅读完成。
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