Taobaolib-flexible.jsプラグインアノテーションバージョン

;

(function(win, lib) {
    var doc = win.document;

    var docEl = doc.documentElement;

    /**

     * 获取例如<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no">的元素

     * */

    var metaEl = doc.querySelector('meta[name="viewport"]');

    /**

     * 获取例如<meta name="flexible" content="initial-dpr=2,maximum-dpr=3" />的元素

     * 其中initial-dpr会把dpr强制设置为给定的值,maximum-dpr会比较系统的dpr和给定的dpr,取最小值。注意:这两个参数只能选其一。

     * */

    var flexibleEl = doc.querySelector('meta[name="flexible"]');

    // 屏幕可视区宽度叫设备独立像素,device independent pixels,简称dip或dp。屏幕能够显示的显示的实际像素数叫做物理像素。

    // 定义设备像素比,像素比window.devicePixelRatio=物理像素/设备独立像素(dips)

    var dpr = 0;

    // 定义视口缩放比例

    var scale = 0;

    // 定义setTimeout返回的值

    var tid;

    // 获取或定义flexible对象

    var flexible = lib.flexible || (lib.flexible = {});

    // 如果存在视口的meta的标签

    if (metaEl) {
        console.warn('将根据已有的meta标签来设置缩放比例');

        var match = metaEl.getAttribute('content').match(/initial\-scale=([\d\.]+)/);

        if (match) {
            // 用正则表达式匹配出缩放比例

            scale = parseFloat(match[1]);

            // 根据缩放比例获取设备像素比

            dpr = parseInt(1 / scale);

        }

    } else if (flexibleEl) {
        // 如果存在弹性meta标签,获取content属性

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

            }

        }

    }

    // 如果设备像素比和缩放比例都没有定义

    if (!dpr && !scale) {
        // 判断是否是安卓平台

        var isAndroid = win.navigator.appVersion.match(/android/gi);

        // 判断是否是ios平台

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

    // 如果视口的meta标签不存在,则重新创建

    if (!metaEl) {
        // 创建meta标签

        metaEl = doc.createElement('meta');

        // 给meta标签增加name属性,指定为视口

        metaEl.setAttribute('name', 'viewport');

        // 给meta标签设置content属性,指定最初的最大的缩放比例和禁止用户手动缩放

        metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');

        // docEl.firstElementChild为head标签  判断有没有head标签

        if (docEl.firstElementChild) {
            // 把meta标签加入到head标签中

            docEl.firstElementChild.appendChild(metaEl);

        } else {
            // 如果不存在head标签,则创建一个div来包裹meta标签

            var wrap = doc.createElement('div');

            wrap.appendChild(metaEl);

            // 插入文档流

            doc.write(wrap.innerHTML);

        }

    }

    // 刷新人

    function refreshRem() {
        // 获取可视区域的宽度

        var width = docEl.getBoundingClientRect().width;

        // 宽度除以设备像素比等于按比例缩放后的宽度,如果这个宽度大于540,那就设置宽度为540乘以设备像素比

        // 就是设置屏幕的宽度极限

        if (width / dpr > 540) {
            width = 540 * dpr;

        }

        // 定义1个rem等于宽度的十分之一

        var rem = width / 10;

        // 给html标签绑定字号 字号等于一个rem

        docEl.style.fontSize = rem + 'px';

        // 给flexiable对象增加rem属性

        flexible.rem = win.rem = rem;

    }

    // 监听窗口变动

    win.addEventListener('resize',

        // 这里运用了函数防抖

        function() {
            // 清除tid

            clearTimeout(tid);

            // 创建tid,300毫秒后执行refreshRem

            tid = setTimeout(refreshRem, 300);

        },

        false);

    // 监听页面展示事件

    win.addEventListener('pageshow',

        function(e) {
            // event.persisted从缓存中获取时为true否则为false

            if (e.persisted) {
                clearTimeout(tid);

                tid = setTimeout(refreshRem, 300);

            }

        },

        false);

    // 当dom加载完成时

    if (doc.readyState === 'complete') {
        // 给body设置字号为12乘以设备像素比

        doc.body.style.fontSize = 12 * dpr + 'px';

    } else {
        // 当初始的 HTML 文档被完全加载和解析完成之后

        doc.addEventListener('DOMContentLoaded',

            function(e) {
                // 给body设置字号为12乘以设备像素比

                doc.body.style.fontSize = 12 * dpr + 'px';

            },

            false);

    }

    // 刷新rem大小

    refreshRem();

    // 给flexible对象增加属性

    flexible.dpr = win.dpr = dpr;

    flexible.refreshRem = refreshRem;

    // rem转为px

    flexible.rem2px = function(d) {
            // 参数乘以一个rem代表的px值

            // parseFloat() 函数可解析一个字符串,并返回一个浮点数。该函数指定字符串中的首个字符是否是数字。如果是,则对字符串进行解析,直到到达数字的末端为止,然后以数字返回该数字,而不是作为字符串。

            var val = parseFloat(d) * this.rem;

            // 如果参数为字符串并且含有rem字符串

            if (typeof d === 'string' && d.match(/rem$/)) {
                // 拼装px

                val += 'px';

            }

            return val;

        }

        //px转为rem

    flexible.px2rem = function(d) {
        // 参数除以rem的长度

        var val = parseFloat(d) / this.rem;

        // 如果参数为字符串并且含有px字符串

        if (typeof d === 'string' && d.match(/px$/)) {
            val += 'rem';

        }

        return val;

    }

 

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

 

おすすめ

転載: blog.csdn.net/liuhao9999/article/details/110060000