⼿淘flexible.js框架使⽤和源代码讲解⼩结
⼿淘框架是⼀个⽤来适配移动端的js框架,下⾯我们来讲解⼀下如何使⽤⼿淘的这套框架。
基本概念
1、视窗viewport
可能写过移动端的朋友就知道viewport是什么意思。
如果你不知道的话,可以简单理解成:浏览器的可视区窗⼝。可能在PC端,viewport就是浏览器窗⼝的宽度⾼度。但在移动端设备上却就有点复杂,具体的详细介绍我就不介绍啦!可以⾃⾏百度...
2、物理像素
物理像素⼜被称为设备像素,他是显⽰设备中⼀个最微⼩的物理部件。每个像素可以根据操作系统设置⾃⼰的颜⾊和亮度。正是这些设备像素的微⼩距离欺骗了我们⾁眼看到的图像效果。
3、设备独⽴像素
设备独⽴像素也称为密度⽆关像素,可以认为是计算机坐标系统中的⼀个点,这个点代表⼀个可以由程
序使⽤的虚拟像素(⽐如说CSS像素),然后由相关系统转换为物理像素。
4、CSS像素
CSS像素是⼀个抽像的单位,主要使⽤在浏览器上,⽤来精确度量Web页⾯上的内容。⼀般情况之下,CSS像素称为与设备⽆关的像素(device-independent pixel),简称DIPs。
5、屏幕密度
屏幕密度是指⼀个设备表⾯上存在的像素数量,它通常以每英⼨有多少像素来计算(PPI)。
6、设备像素⽐
设备像素⽐简称为dpr,其定义了物理像素和设备独⽴像素的对应关系。它的值可以按下⾯的公式计算得到:
设备像素⽐ = 物理像素 / 设备独⽴像素
众所周知,iPhone6的设备宽度和⾼度为375pt * 667pt,可以理解为设备的独⽴像素;⽽其dpr为2,根据上⾯公式,我们可以很轻松得知其物理像素为750pt * 1334pt。
其实⼿淘框架的核⼼原理就是根据不同的width给⽹页中html跟节点设置不同的font-size,然后所有的距离⼤⼩都⽤rem来代替,这样就实现了不同⼤⼩的屏幕都适应相同的样式了,⾸先我们来说⼀下常⽤的移动设备。
iphone6: 375px*667px 实际像素:750px*1334px
iphone5: 320px*568px 实际像素:640px*1136px
iphone4: 320px*480px 实际像素:640px*960px
nexus5X(安卓): 411px *731px 实际像素:411px*731px
以上数据都来⾃于chrome浏览器--
其实我们的iphone⼿机都是视⽹膜屏幕,所以我们的实际像素因该是⽆⼒像素*视⽹膜屏的倍数。
然⽽我们在实际的开发中ui给出的图⼀般都是750X1334的,其实iphone6的像素和ui设计的像素是⼀样⼤⼩的,但是我们的开发如果都是按照6的px来设计,那么我们的其它⽐6⼩尺⼨屏幕的所有设备都会⾯临width不够的问题。flexible就完美的解决了这个问题。
应⽤中我们只要设置好他的公共⽐的像素就ok了,⽐如说如果ui图的像素是750,那我们需要的就是750/10,我们需要的就是75,我们所有的width的固定px就都可以变换成⽤rem像素代替实现样式统⼀例如我们width需要200px那么我们就可以这样写:
width=200rem/75;从⽽实现样式的兼容(特别注意:因为css不⽀持样式的计算,我们需要⽤less活着sass类似的css编译执⾏就可以得到最终的rem的值了)
另外,我们根据不同dpr可以设置⼀些不同的样式来实现视⽹膜屏幕的⾼清屏幕!
[data-dpr="1"] .selector {
width: 10px;
height: 32px;
font-size: 14px;
}
[data-dpr="2"] .selector {
width: 20px;
height: 64px;
font-size: 28px;
}
我们根据不同的⾃定义属性data-dpr来设置不同的width和height 从⽽达到不同dpr屏幕具有不同的属性!(这个位置⼀般⽤来处理图⽚。。)
下⾯我们来讲解⼀下flexible的源代码:
;(function(win, lib) {
})(window, window['lib'] || (window['lib'] = {}));
⾸先这个最外层结构是最基本的封装类库的⽅法:函数⽴即调⽤,这样可以防⽌封装⽅法污染全局变量,jquery的源码也是⼀样的道理!
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 = {});
doc取⽂档的document对象
docEl取到了我们html为根的整个dom树,后期我们需要向html插⼊dpr和font-size就是⽤这个属性
metaEl取meta标签⾥⾯name=viewport的元素,没有返回空,为了判断是否有⾃⼰设置的meta值来做⼀些逻辑
flexibleEl取meta标签⾥⾯name=flexible的元素,没有返回空,为了判断⽤户是否⾃⼰⼿动的设置了⼀些meta值
dpr表⽰的是取你⼿机屏幕的dpr值
scale表⽰取你meta⾥⾯的scale,会根据不同的scale设置dpr
我们需要了解的⼤概就是上⾯的这些需要⽤到的属性!
if (metaEl) {
console.warn('将根据已有的meta标签来设置缩放⽐例');
var match = Attribute('content').match(/initial\-scale=([\d\.]+)/);
if (match) {
scale = parseFloat(match[1]);
dpr = parseInt(1 / scale);
}
} else if (flexibleEl) {
var content = Attribute('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标签⾥⾯是不是设置了name=viewport属性,如果你设置了viewport并且设置了initial-scale(初始屏幕的⼤⼩)我们将取到这个值作为dpr(做了逻辑运算,如果你的页⾯初始的放⼤为⼆,那么我们的dpr会设置成0)
同理我们如果动态设置了meta我们直接就取出来然后设置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;
}
docEl.setAttribute('data-dpr', dpr);
之后如果我们动态设置了scale或者设置了meta标签⾥⾯的name=flexible的inital-scale,那么我们就根据⾃⼰设置的dpr在判断iphone⼿机的retina屏幕的dpr⽐值判断不同型号的倍数,最后我们在html上设置了data-dpr⾃定义属性。
if (!metaEl) {
metaEl = ateElement('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 = ateElement('div');
wrap.appendChild(metaEl);
doc.write(wrap.innerHTML);
}
}
之后当我们之前没有设置metaEl标签的话,那么需要我们⼿动的去创建meta标签,实现移动端的适配
function refreshRem(){
var width = BoundingClientRect().width;
if (width / dpr > 540) {
width = 540 * dpr;
jquery源码在线}
var rem = width / 10;
docEl.style.fontSize = rem + 'px';
< = = 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);
这段代码的⽬的就是监听window⾥⾯的resize和pageshow⽅法来实现css样式的重绘。
函数⾥⾯就是实现取到当前设备的width之后根据width计算出rem的具体值,rem代表html的font-size,这⾥的rem代表的是⼀个⾃定义的rem,⽽不是rem属性!
if (adyState === 'complete') {
doc.body.style.fontSize = 12 * dpr + 'px';
} else {
doc.addEventListener('DOMContentLoaded', function(e) {
doc.body.style.fontSize = 12 * dpr + 'px';
}, false);
}
之后我们判断document对象是否处于complete状态,如果完成状态我们给body⼀个font-size=12*dpr的值,否则我们判断dom加载⽅法来实现body中的font-size的设置。这个设置是为了页⾯中字体的⼤⼩,⽽html中的font-size是为了设置页⾯的height,width等属性。
以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论