flexible.js 弹性布局分析与实战
作为一名小白,不思进取,还荒废了好长一段时间,一直没有总结学习,内心很愧疚...从这周开始,坚持每周积累自己的笔记,努力学习,成为一名合格的攻城狮!
flexible.js 分析
首先,我先引用flexible.js作者对这个脚本的解释:通过js事实的检测屏幕的大小并改变html标签的字体大小,再结合rem的特性来完成页面的自适应。
/* 最基本的封装类库的方法:函数立即调用,防止封装方法污染全局变量 */ (function flexible(window, document) { // 取html为根的整个dom树 var docEl = document.documentElement // 设备像素比devicePixelRatio,没法获取就为 1 var dpr = window.devicePixelRatio || 1 console.log(docEl); // 获取 root 节点 console.log(dpr); // 2 console.log(window); // Window console.log(window.body); // undefined console.log(document); // 获取 body 节点 console.log(document.body); // null 此时dom没有完全加载,所以为空 // JS代码写在head中,一加载就执行,此时后面的body还没有加载出来,故为null // adjust body font size function setBodyFontSize() { // document.body 为 null if (document.body) { // true时,设置字体大小 document.body.style.fontSize = (12 * dpr) + 'px' } else { // 监听 DOM 加载,调用 setBodyFontSize 设置字体大小 document.addEventListener('DOMContentLoaded', setBodyFontSize) } } setBodyFontSize(); // set 1rem = viewWidth / 10 function setRemUnit() { // 可视区域的宽度 / 10 var rem = docEl.clientWidth / 10 // 设置字体大小 docEl.style.fontSize = rem + 'px' } setRemUnit() // reset rem unit on page resize // 监听盒子的size变化事件,变化了就调用setRemUnit函数,设置html根字体大小 window.addEventListener('resize', setRemUnit) // pageshow 页面显示时触发 window.addEventListener('pageshow', function (e) { console.log(e.persisted); // false if (e.persisted) { setRemUnit() } }) /* retina屏的浏览器可能不认识 0.5px 的边框,将会把它解释成0px,没有边框。 包括 iOS 7 和 之前版本,OS X Mavericks 及以前版本,还有 Android 设备。 解决方案:解决方案是通过JS判断是否支持0.5px的边框,给<html>元素添加上 hairlines的类名,就可以认识0.5px的边框了*/ // detect 0.5px supports // 如果 设备像素比devicePixelRatio >= 2 if (dpr >= 2) { // 创建 新的 body var fakeBody = document.createElement('body') // 测试 div var testElement = document.createElement('div') // 测试div加 0.5px 的透明边框 testElement.style.border = '.5px solid transparent' // 将这个测试div加到 新创建的 body 中 fakeBody.appendChild(testElement) // 将新创建的 body 添加到 HTML 节点中 docEl.appendChild(fakeBody) // 如果测试div高度为1 // offsetHeight高度包含该元素的垂直内边距和边框,且是一个整数。 /* 因为Retine屏的分辨率始终是普通屏幕的2倍, 1px的边框在devicePixelRatio=2的retina屏下会显示成2px。 */ if (testElement.offsetHeight === 1) { docEl.classList.add('hairlines') // “retina hairlines”(retina 极细的线) } // 移除 body docEl.removeChild(fakeBody) } }(window, document))
rem:rem为元素设定字体大小时,仍然是相对大小,但相对的只是HTML根元素。这个单位可谓集相对大小和绝对大小的优点于一身,通过它既可以做到只修改根元素就成比例地调整所有字体大小,又可以避免字体大小逐层复合的连锁反应。
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>手淘布局</title> <!-- 重置样式 --> <link rel="stylesheet" href="./css/reset.css"> <!-- 自己样式 --> <link rel="stylesheet" href="./css/index.css"> <!-- 插件 --> <script src="./assets/flexible/index.min.js"></script> </head> <body> <div class="container"> <!-- 标题 --> <div class="top"> <img class="back" src="./images/fanhui.png"> <div class="search"> <img class="img_search" src="./images/fangdajing.png"> <input class="inp" type="text" placeholder="请输入內容" value=""> <img class="img_clear" src="./images/chahao.png"> </div> </div> <!-- 抽奖 --> <ul> <!-- 已中奖人数 --> <li> <section class="sec"> <div class="t_bank">已中奖人数</div> <div class="t_bank_num">3個</div> <img src="./images/jiantou2.png"> </section> <!-- 细节 --> <ul class="details"> </ul> </li> <!-- 未中奖人数 --> <li> <section class="sec"> <div class="t_bank">未中奖人数</div> <div class="t_bank_num">3個</div> <img src="./images/jiantou2.png"> </section> <!-- 细节 --> <ul class="details"> </ul> </li> </ul> </div> </body> </html>
通过手淘插件,实现了移动端布局,不需要直接设置:root的font-size为px,因为在flexible.js中动态监听font-size的大小
其他font-size设置为rem;padding、margin、left、top 一般设置为%;
注意,一般不要给body设置height,在移动端会自动适应
代码已上传文件,感兴趣的同学可以学习一下
链接:https://pan.baidu.com/s/1ZRQwHo8YZhQiYYvzY15iZQ 密码:2k34