参考答案:
flexible.js 官方已不再维护,目前推行 vw 适配方案,本答案只是为了分析它的原理。
flexible.js存在的目的,是为了让网页在各终端上的展示效果就像缩放设计稿图片一样,在不同屏幕上等比缩放,每一个元素与整体比例保持不变,真实还原设计稿。
设页面宽度为P(单位px)
设计稿宽度为750px
设html基准值为X(单位px)
首先将页面分为100份,份的单位为F
设1F的像素值为A(单位px/F)
那么:
P = 100F * A
A = P/100F
当P为750时,A=7.5px/F,即一份为7.5px
有没有感觉这个A有点熟悉,没错它就是X,上面份的单位F其实就是rem。
(html font-size的基准值单位虽然写为px,但其实是px/F,这点你知道就可以了)
现在懂了吧。
rem的原理就是份,我们根据设计稿得到元素的份,写到代码中的也是份,现在只要动态改变html的基准值,就能够在不同屏幕下适配,从而还原设计稿尺寸了。
所以flexible.js的原理主要是:
window.onresize = function() { html.size = P/100 + 'px' }
当然针对高清屏,它还会设置“viewport scale”,以缩放页面,解决类似高清屏下无法实现1px边框等问题。
需要注意的是,基准值其实是个动态值,只是在写代码时,我们是按照设计稿宽度计算的基准值写的rem,即以设计稿为标准进行屏幕适配的(将设计稿用代码还原成UI界面),但在实际运行时,页面宽度是动态的,所以基准值也是动态的哦。
flexible.js 的源码并不多,总共不到 50 行:
1// 首先是一个立即执行函数,执行时传入的参数是window和document 2(function flexible (window, document) { 3 var docEl = document.documentElement // 返回文档的root元素 4 var dpr = window.devicePixelRatio || 1 5 // 获取设备的dpr,即当前设置下物理像素与虚拟像素的比值 6 7 // 调整body标签的fontSize,fontSize = (12 * dpr) + 'px' 8 // 设置默认字体大小,默认的字体大小继承自body 9 function setBodyFontSize () { 10 if (document.body) { 11 document.body.style.fontSize = (12 * dpr) + 'px' 12 } else { 13 document.addEventListener('DOMContentLoaded', setBodyFontSize) 14 } 15 } 16 setBodyFontSize(); 17 18 // set 1rem = viewWidth / 10 19 // 设置root元素的fontSize = 其clientWidth / 10 + ‘px’ 20 function setRemUnit () { 21 var rem = docEl.clientWidth / 10 22 docEl.style.fontSize = rem + 'px' 23 } 24 25 setRemUnit() 26 27 // 当页面展示或重新设置大小的时候,触发重新 28 window.addEventListener('resize', setRemUnit) 29 window.addEventListener('pageshow', function (e) { 30 if (e.persisted) { 31 setRemUnit() 32 } 33 }) 34 35 // 检测0.5px的支持,支持则root元素的class中有hairlines 36 if (dpr >= 2) { 37 var fakeBody = document.createElement('body') 38 var testElement = document.createElement('div') 39 testElement.style.border = '.5px solid transparent' 40 fakeBody.appendChild(testElement) 41 docEl.appendChild(fakeBody) 42 if (testElement.offsetHeight === 1) { 43 docEl.classList.add('hairlines') 44 } 45 docEl.removeChild(fakeBody) 46 } 47}(window, document))
最近更新时间:2024-08-10