淘宝实用lib-flexible来适配各类大小的屏幕

####淘宝实用lib-flexible来适配各类大小的屏幕,如今来说讲适配的原理html

  1. 使用方法
<script src="src/lib-flexible.js"></script>
复制代码
  1. 源码解析
;(function(win, lib) {
    var doc = win.document;
    var docEl = doc.documentElement;
    var metaEl = doc.querySelector('meta[name="viewport"]');
    var flexibleEl = doc.querySelector('meta[name="flexible"]');
    var dpr = 0;
    var scale = 0;
    var tid;
    var flexible = lib.flexible || (lib.flexible = {});
   /*将根据已有的meta标签来设置缩放比例*/
    if (metaEl) {
        var match = metaEl.getAttribute('content').match(/initial\-scale=([\d\.]+)/);
        if (match) {
            scale = parseFloat(match[1]);
            dpr = parseInt(1 / scale);
        }
    } else if (flexibleEl) {
        var content = flexibleEl.getAttribute('content');
        if (content) {
            var initialDpr = content.match(/initial\-dpr=([\d\.]+)/);
            var maximumDpr = content.match(/maximum\-dpr=([\d\.]+)/);
            if (initialDpr) {
                dpr = parseFloat(initialDpr[1]);
                scale = parseFloat((1 / dpr).toFixed(2));
            }
            if (maximumDpr) {
                dpr = parseFloat(maximumDpr[1]);
                scale = parseFloat((1 / dpr).toFixed(2));
            }
        }
    }
    /*当原先没有设置过meta,以及缩放比例
    * iphone手机根据2,3屏幕处理
    * 其余设备下,仍旧使用1倍的方案  获得dpr和scale的值
    * */
    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;
    }
    /*设置html的data-dpr的值*/
    docEl.setAttribute('data-dpr', dpr);
    /*
    *scale
    * 查询有没有meta属性,没有的状况下加上 <meta content='initial-scale= scale, maximum-scale=scale, minimum-scale=scale, user-scalable=no/> * */ if (!metaEl) { metaEl = doc.createElement('meta'); metaEl.setAttribute('name', 'viewport'); metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no'); if (docEl.firstElementChild) { docEl.firstElementChild.appendChild(metaEl); } else { var wrap = doc.createElement('div'); wrap.appendChild(metaEl); doc.write(wrap.innerHTML); } } /* * 这个width跟dpr有关系 例如iphone5 dpr为2 获得的屏幕的宽为640px * 例如iphone6 plus dpr为3 获得的屏幕的宽为1242px * */ function refreshRem(){ var width = docEl.getBoundingClientRect().width; //注意这里,这里是适配手机的一个具体的参数,相对大于540的就不适用了 if (width / dpr > 540) { width = 540 * dpr; } var rem = width / 10; docEl.style.fontSize = rem + 'px'; flexible.rem = win.rem = rem; } win.addEventListener('resize', function() { clearTimeout(tid); tid = setTimeout(refreshRem, 300); }, false); win.addEventListener('pageshow', function(e) { if (e.persisted) { clearTimeout(tid); tid = setTimeout(refreshRem, 300); } }, false); if (doc.readyState === 'complete') { doc.body.style.fontSize = 12 * dpr + 'px'; } else { doc.addEventListener('DOMContentLoaded', function(e) { doc.body.style.fontSize = 12 * dpr + 'px'; }, false); } refreshRem(); /*rem转px px转rem*/ flexible.dpr = win.dpr = dpr; flexible.refreshRem = refreshRem; flexible.rem2px = function(d) { var val = parseFloat(d) * this.rem; if (typeof d === 'string' && d.match(/rem$/)) { val += 'px'; } return val; } flexible.px2rem = function(d) { var val = parseFloat(d) / this.rem; if (typeof d === 'string' && d.match(/px$/)) { val += 'rem'; } return val; } })(window, window['lib'] || (window['lib'] = {})); 复制代码
  1. 先来了解一点关于viewport的知识,一般咱们采用以下代码设置viewport:
  2. <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
  3. 这样整个网页在设备内显示时的页面宽度就会等于设备逻辑像素大小,也就是device-width。这个device-width的计算公式为:

设备的物理分辨率/(devicePixelRatio * scale),在scale为1的状况下,device-width = 设备的物理分辨率/devicePixelRatio 。前端

devicePixelRatio称为设备像素比,每款设备的devicePixelRatio都是已知,而且不变的,目前高清屏,广泛都是2,不过还有更高的,好比2.5, 3 等,我魅族note的手机的devicePixelRatio就是3。淘宝触屏版布局的前提就是viewport的scale根据devicePixelRatio动态设置:android

  1. 这么作目的固然是为了保证页面的大小与设计稿保持一致了,好比设计稿若是是750的横向分辨率,那么实际页面的device-width,以iphone6来讲,也等于750,这样的话设计稿上标注的尺寸只要除以某一个值就可以转换为rem了。经过js设置viewport的方法以下:
  2. 接下来要解决的问题是,元素的尺寸该如何计算,好比说设计稿上某一个元素的宽为150px,换算成rem应该怎么算呢?这个值等于设计稿标注尺寸/该设计稿对应的html的font-size。拿淘宝来讲的,他们用的设计稿是750的,因此html的font-size就是75,若是某个元素时150px的宽,换算成rem就是150 / 75 = 2rem。总结下淘宝的这些作法:
  3. 最后还有一个状况要说明,跟网易同样,淘宝也设置了一个临界点,当设备竖着时横向物理分辨率大于1080时,html的font-size就不会变化了,缘由也是同样的,分辨率已经能够去访问电脑版页面了。
  4. https://github.com/amfe/lib-flexible

如何与设计协做

  1. 第一步,视觉设计阶段,设计师按宽度750px(iphone 6)作设计稿,除图片外全部设计元素用矢量路径来作。设计定稿后在750px的设计稿上作标注,输出标注图。同时等比放大1.5倍生成宽度1125px的设计稿,在1125px的稿子里切图。
  2. 第二步,输出两个交付物给开发工程师:一个是程序用到的@3x切图资源,另外一个是宽度750px的设计标注图。
  3. 第三步,开发工程师拿到750px标注图和@3x切图资源,完成iPhone 6(375pt)的界面开发。此阶段不能用固定宽度的方式开发界面,得用自动布局(auto layout),方便后续适配到其它尺寸。
  4. 第四步,适配调试阶段,基于iPhone 6的界面效果,分别向上向下调试iPhone 6 plus(414pt)和iPhone 5S及如下(320pt)的界面效果。由此完成大中小三屏适配。

####参考 前端开发博客(没有找到名字的人)git

相关文章
相关标签/搜索