0
点赞
收藏
分享

微信扫一扫

淘宝lib-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'] = {}));



举报

相关推荐

0 条评论