前言
移动端适配一直以来都是前端开发中不可或缺的重要组成部分,若是没有了它,那么你作出来的页面极有可能会出现各类意外(写出来的页面与设计稿之间的差异)。全部咱们得找到一种相对来讲让人比较满意的解决方案,尽量地让这种“意外”减到最少。没错今天的主角就是它“flexible.js” 。javascript
flexible.js 之旅
flexible.js 的做用就是让你在不一样的终端设备之间如鱼得水,如入无人之境。说得那么浮,一点感受都没有。不急,咱们慢慢来,一步一步走进 flexible.js 神秘的世界。css
flexible.js 有什么用
正如文章标题所写的那样,它就是一个终端设备适配的解决方案。也就是说它可让你在不一样的终端设备中实现页面适配。html
flexible.js 怎么用
flexible.js 的用法很是的简单,在页面的<head></head>中引入 flexible_css.js,flexible.js文件:前端
// 加载阿里CDN的文件
<script src="http://g.tbcdn.cn/mtb/lib-flexible/0.3.4/??flexible_css.js,flexible.js"></script>
除了上面这种方式外,你还能够把这两个文件下载到本身的项目中,而后再引入,效果是同样的。java
上面两个文件其实就是一个 .css 文件和一个 .js 文件:android
@charset "utf-8"; html{color:#000;background:#fff;overflow-y:scroll;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%} html *{outline:0;-webkit-text-size-adjust:none;-webkit-tap-highlight-color:rgba(0,0,0,0)} html,body{font-family:sans-serif} body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td,hr,button,article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{margin:0;padding:0} input,select,textarea{font-size:100%} table{border-collapse:collapse;border-spacing:0} fieldset,img{border:0} abbr,acronym{border:0;font-variant:normal} del{text-decoration:line-through}address,caption,cite,code,dfn,em,th,var{font-style:normal;font-weight:500} ol,ul{list-style:none} caption,th{text-align:left} h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:500} q:before,q:after{content:''} sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline} sup{top:-.5em} sub{bottom:-.25em} a:hover{text-decoration:underline} ins,a{text-decoration:none}
一看就知道这个 .css 文件是用来干吗的了。git
(function(win, lib) { 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 = {}); 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) { 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); 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); if (!metaEl) { metaEl = doc.createElement('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 = doc.createElement('div'); wrap.appendChild(metaEl); doc.write(wrap.innerHTML); } } function refreshRem(){ var width = docEl.getBoundingClientRect().width; if (width / dpr > 540) { width = 540 * dpr; } var rem = width / 10; docEl.style.fontSize = rem + 'px'; flexible.rem = win.rem = 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); if (doc.readyState === 'complete') { doc.body.style.fontSize = 12 * dpr + 'px'; } else { doc.addEventListener('DOMContentLoaded', function(e) { doc.body.style.fontSize = 12 * dpr + 'px'; }, false); } refreshRem(); flexible.dpr = win.dpr = dpr; flexible.refreshRem = refreshRem; flexible.rem2px = function(d) { var val = parseFloat(d) * this.rem; if (typeof d === 'string' && d.match(/rem$/)) { val += 'px'; } return val; } flexible.px2rem = function(d) { var val = parseFloat(d) / this.rem; if (typeof d === 'string' && d.match(/px$/)) { val += 'rem'; } return val; } })(window, window['lib'] || (window['lib'] = {}));
不要以为这个.js 文件的内容多,由于其核心代码也就十几二十行。其实上面两个文件的内容都基本都不须要怎么看,你只须要引入它们就好。github
接下来你要作的就是在页面中使用这个解决方案给你提供套路。说真的套路其实就是以根节点为基准值,而后就没有而后了……,官方有这么一段话,你能够好好感觉下:web
提示
另外强烈建议对JS作内联处理,在全部资源加载以前执行这个JS。执行这个JS后,会在元素上增长一个data-dpr属性,以及一个font-size样式。JS会根据不一样的设备添加不一样的data-dpr值,好比说2或者3,同时会给html加上对应的font-size的值,好比说75px。 如此一来,页面中的元素,均可以经过rem单位来设置。他们会根据html元素的font-size值作相应的计算,从而实现屏幕的适配效果。sass
事实上 flexible.js 作了下面三件事:
- 动态改写标签
- 给<html>元素添加data-dpr属性,而且动态改写data-dpr的值
- 给<html>元素添加font-size属性,而且动态改写font-size的值
官方粟子:
下图为一个简单得不能再简单的示意图(伪装它是一个宽为 750px 的移动端设计稿):
图片虽然丑了一点,那能说明意思就足够了,请看左边的那几条红线以主旁边的标注。如今咱们来伪装要作一个页面(设计稿宽为 750px)。在这个例子中咱们只是想说明如何使用flexible.js ,其它的暂时不考虑在内。在开始以前,咱们还有必要研读下这句话:
提示
目前Flexible会将视觉稿分红**100份**(主要为了之后能更好的兼容vh和vw),而每一份被称为一个单位a。同时1rem单位被认定为10a。针对咱们这份视觉稿能够计算出:
换算
1a = 7.5px
1rem = 75px
上面这一小段提示能够说是 flexible.js 的精华所在了。但你只须要记住1rem = 75px 就好。好比上面云库网这个 LOGO 距离左边60px,上边42px,图片自身宽、高都是80px。固然你也能够直接用这些数值:
.logo{
width:80px;
height:80px;
margin-left:60px;
margin-top:42px;
}
但咱们是要在移动端作适配的,这样写还有什么适配可言?咱们能够把上面的像素转换成 rem。rem 是根据根元素(html 的字体大小)来进行计算的,这样就能够很方便地让咱们把设计稿等比缩放到与实践终端相匹配的大小。
.logo{
width: 1.066667rem;
height: 1.066667rem;
margin-left: 0.8rem;
margin-top: 0.56rem;
}
说得简单点就是 rem 至关于咱们日常用的百分比,只不过 rem 是相对根元素的。而咱们的根元素是根据终端屏幕大小来动态设置的,因此不论是 iphone 6 plus (尺寸为414*736)仍是 iphone 6 (尺寸为375*667),或者是其它任何终端设备均可以很完美地还原设计稿。
还有一个关于 px 转 rem 的,你也不用本身一个一个手动去换算,这里有一个插件你能够安装下,它会自动地帮你把 px 换算成 rem 。
传送门:https://github.com/flashlizi/cssrem
安装方法也很简单:
- 下载本项目,好比:git clone https://github.com/flashlizi/cssrem
- 进入packages目录:Sublime Text -> Preferences -> Browse Packages…
- 复制下载的cssrem目录到刚才的packges目录里。
- 重启Sublime Text。
参数配置:
参数配置文件:Sublime Text -> Preferences -> Package Settings -> cssrem
- px_to_rem – px转rem的单位比例,默认为40。
- max_rem_fraction_length – px转rem的小数部分的最大长度。默认为6。
- available_file_types – 启用此插件的文件类型。默认为:[“.css”, “.less”, “.sass”]。
这里有一个插件的效果图(来自官方):
简单、易用、你值得下载用一用!
参考资料
https://github.com/amfe/lib-flexible
https://github.com/flashlizi/cssrem
其它更多的详细内容,你能够到这两个网站中阅读,本文也只能送你到这里了。