当前位置:网站首页>手写简易版flexible.js以及源码分析
手写简易版flexible.js以及源码分析
2022-07-04 07:14:00 【馆主阿牛】
个人简介
- 作者简介:大家好,我是阿牛,全栈领域新星创作者。
- 个人主页:馆主阿牛
- 支持我:点赞+收藏️+留言
- 系列专栏:硬泡 javascript
- 格言:要成为光,因为有怕黑的人!
前言
我们的移动端布局通常会有rem结合媒体查询的实现,但是,淘宝有这样的一个flexible.js框架,根据不同的width给网页中html根节点设置不同的font-size,大大提高了我们的开发效率,今天阿牛便带你手写一个简易版flexible.js并解读,了解他的大致原理。
flexible.js是什么?
flexible.js手淘框架,是淘宝开发的一个用来适配移动端的js框架。
手淘框架的核心原理就是根据不同的width给网页中html根节点设置不同的font-size,然后所有的距离大小都用rem来代替,这样就实现了不同大小的屏幕都适应相同的样式了。
rem适配布局介绍
rem ( root em )是一个相对单位,类似于 em , em 是父元素字体大小。不同的是 rem 的基准是相对于 htm 元素的字体大小。
比如,根元素( html )设置 font - size =12px;非根元素设置width:2rem;则换成 px 表示就是24px.
rem的优点是可以通过修改html里面的文字大小来改变页面中元素的大小,可以整体控制。
通常在网页布局中,我们可以结合媒体查询+rem实现元素变化,即不同像素的屏幕对应的根html标签的样式font-size的值不同。像下面这样:
@media (min-width:860px){
html{
font-size:50px;
}
}
简易版flexible.js源码分析
(function flexible(window,document){
// 获取html的根元素
var docEl = document.documentElement;
// dpr 物理像素比 window.devicePixelRatio 会获取当前屏幕的物理像素比,如果是pc端则为1,移动端为2。
// 如果当前浏览器没有window.devicePixelRatio则取1
var dpr = window.devicePixelRatio || 1;
// 设置body的字体大小
function setBodyFontSize(){
// 如果页面有body这个元素,就设置body的字体大小
if (document.body){
document.body.style.fontSize = (12 * dpr) + 'px';
}else{
//否则,等待页面的主要DOM元素加载完毕再去设置body的字体大小
document.addEventListener("DOMContentLoaded",setBodyFontSize);
}
}
setBodyFontSize();
// 核心
// 设置html的文字大小
function setRemUnit(){
// 将html文档宽度划分为10等分,每一等分为一rem,即html的fontsize
var rem = docEl.clientWidth / 10;
docEl.style.fontSize = rem + 'px';
}
setRemUnit();
// 当页面尺寸大小发生变化时,要重新设置rem的大小
window.addEventListener('resize',setRemUnit);
// pageshow 是我们重新加载页面触发的事件
window.addEventListener('pageshow',function(e){
if(e.persisted){
// 返回的是true,说明这个页面是从缓存中去过来的页面,也需要重新计算一下rem的大小
setRemUnit();
}
})
// 下面这块不必了解
// detect 0.5px supports // 有些移动端浏览器不支持0.5像素的写法,下面这个解决方案可以让其支持
if(dpr >= 2){
var fakeBody = document.createElement('body');
var testElement = docunment.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))
示例
<!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>Document</title>
<script src="flexible.js"></script>
</head>
<body>
</body>
</html>
我的谷歌浏览器物理像素比为1.25
注:
1.javascript中的立即执行函数:
(function () {}() 或者 (function(){} ())
立即执行函数不需要调用就可以执行,第二个小括号可以看做是调用函数。可以给参数,也可以给匿名函数给函数名。
(function sum(a,b){
return a + b;} (1,2))
2.pageshow事件
下面三种情况都会刷新而面都会触发 load 事件
- a 标签的超链接
- F5或者刷新按钮(强制刷新)
- 前进后退接钮
但是火狐中,有个特点,有个“往返缓存”,这个缓存中不仅保存着页面数据,还保存了 DOM和JavaScript 的状态;实际上是将整个页面都保存在了内存里
所以此时后退按钮不能刷新页面。
此时可以使用 pageshow 事件来触发。这个事件在页面显示时触发,无论是否是来自缓存。在重新加载页面中, pageshow 会在 load 事件触发后触发;根据事件对象中的 persisted 判断是否是缓存中的页面触发的 pageshow 事件,注意这个事件给 window 添加。
结语
用这个flexible.js后,你可能需要再装一个cssrem插件,这个插件会自动将你的px转换为rem,提高开发效率,综合来说flexible.js还不错,不用写媒体查询了,且html的fontsize是划分的,一直会随页面大小动态变化,从而实现元素的大小变化。
如果你觉得博主写的还不错的话,可以关注一下当前专栏,博主会更完这个系列的哦!也欢迎订阅博主的其他好的专栏。
边栏推荐
- MySQL storage engine
- Su Weijie, a member of Qingyuan Association and an assistant professor at the University of Pennsylvania, won the first Siam Youth Award for data science, focusing on privacy data protection, etc
- Introduction to spark core components
- A new understanding of how to encrypt industrial computers: host reinforcement application
- socket inet_ pton() inet_ Ntop() function (a new network address translation function, which converts the expression format and numerical format to each other. The old ones are inet_aton(), INET_ ntoa
- Pangu open source: multi support and promotion, the wave of chip industry
- MySQL relearn 2- Alibaba cloud server CentOS installation mysql8.0
- Zabbix agent主动模式的实现
- The number of patent applications in China has again surpassed that of the United States and Japan, ranking first in the world for 11 consecutive years
- Review of enterprise security incidents: how can enterprises do a good job in preventing source code leakage?
猜你喜欢
Centos8 install mysql 7 unable to start up
【Kubernetes系列】Kubernetes 上安装 KubeSphere
Rhcsa day 3
Two years ago, the United States was reluctant to sell chips, but now there are mountains of chips begging China for help
期末周,我裂开
CMS source code of multi wechat management system developed based on thinkphp6, with one click curd and other functions
Responsive - media query
Introduction to deep learning Ann neural network parameter optimization problem (SGD, momentum, adagrad, rmsprop, Adam)
Solution of running crash caused by node error
Splicing plain text into JSON strings - easy language method
随机推荐
com. alibaba. nacos. api. exception. NacosException
Literature collation and thesis reading methods
Paddleocr prompt error: can not import AVX core while this file exists: xxx\paddle\fluid\core_ avx
leetcode825. 适龄的朋友
socket inet_ pton() inet_ Ntop() function (a new network address translation function, which converts the expression format and numerical format to each other. The old ones are inet_aton(), INET_ ntoa
MySQL error resolution - error 1261 (01000): row 1 doesn't contain data for all columns
MySQL storage engine
两年前美国芯片扭捏着不卖芯片,如今芯片堆积如山祈求中国帮忙
A new understanding of how to encrypt industrial computers: host reinforcement application
How can the old version of commonly used SQL be migrated to the new version?
Recursive Fusion and Deformable Spatiotemporal Attention for Video Compression Artifact Reduction
Download address of the official website of national economic industry classification gb/t 4754-2017
Rhcsa the next day
centos8安装mysql.7 无法开机启动
Mobile adaptation: vw/vh
MySQL 45 lecture learning notes (x) force index
Research on an endogenous data security interaction protocol oriented to dual platform and dual chain architecture
The crackdown on Huawei prompted made in China to join forces to fight back, and another enterprise announced to invest 100 billion in R & D
The final week, I split
Why does the producer / consumer mode wait () use while instead of if (clear and understandable)