前端小工具:flexible.js实现rem自适应
Posted smallbore
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了前端小工具:flexible.js实现rem自适应相关的知识,希望对你有一定的参考价值。
前端小工具:flexible.js实现rem自适应
通过js来调整html的字体大小,而在页面中的制作稿则统一使用rem这个单位来制作。关键代码如下:
;(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) { 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\'] = {}));
使用rem函数转换
export function rem(px) { return `${(px / 75).toFixed(2)}rem`; }
smallbore,world
使用 sass + rem + flexible.js 实现大屏自适应
可伸缩布局方案 flexible.js
首先需要准备 flexible.js
:https://github.com/amfe/lib-flexible/blob/2.0/index.js
flexible.js 处理了什么问题:
- 1px 问题,当 dpr 大于等于 2 的时候,将 border 都设置为 0.5px
- 根据页面宽度设置 rem
- 根据 dpr 设置 body 下的 fontsize
下面是源码:
window.devicePixelRatio
:获取设备像素比(设备像素比 = 物理像素 / 设备独立像素)- pageshow:当一条会话历史记录被执行的时候将会触发页面显示 pageshow 事件
(function flexible (window, document)
var docEl = document.documentElement
var dpr = window.devicePixelRatio || 1
// adjust body font size
function setBodyFontSize ()
if (document.body)
document.body.style.fontSize = (12 * dpr) + 'px'
else
document.addEventListener('DOMContentLoaded', setBodyFontSize)
setBodyFontSize();
// set 1rem = viewWidth / 10
function setRemUnit ()
var rem = docEl.clientWidth / 10
docEl.style.fontSize = rem + 'px'
setRemUnit()
// reset rem unit on page resize
window.addEventListener('resize', setRemUnit)
window.addEventListener('pageshow', function (e)
if (e.persisted)
setRemUnit()
)
// detect 0.5px supports
if (dpr >= 2)
var fakeBody = document.createElement('body')
var testElement = document.createElement('div')
testElement.style.border = '.5px solid transparent'
fakeBody.appendChild(testElement)
docEl.appendChild(fakeBody)
if (testElement.offsetHeight === 1)
docEl.classList.add('hairlines')
docEl.removeChild(fakeBody)
(window, document))
1、页面引入 flexible.js
在页面 html 文件里引入 flexible.js
。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title><%= htmlWebpackPlugin.options.title %></title>
<script src="/lib/flexible.js"></script>
</head>
<body>
<div id="app"></div>
</body>
</html>
引入之后我们可以看一下 f12,元素一栏里查看 html 根元素是否有 font-size:
2、编写 p2r 函数
根据设计稿去划分份数:比如:设计稿为 1920 * 1080,开发时候将设计稿分为 10 份方便计算,所以得到 1rem = 1920 / 10
在工具样式文件里 utils.scss
编写 p2r 函数。
@function p2r($size)
@return $size / 192 * 1rem;
3、使用
下面我们根据设计稿的尺寸就可以编写样式了
比如:设计稿的字体是 16px
@import "@/assets/scss/utils.scss";
.kaimo
font-size: p2r(16);
font-weight: 400;
color: #ffffff;
以上是关于前端小工具:flexible.js实现rem自适应的主要内容,如果未能解决你的问题,请参考以下文章
0082 rem适配方案:less+rem+媒体查询flexible.js+rem