• 手写简易版flexible.js以及源码分析


    📋 个人简介

    • 💖 作者简介:大家好,我是阿牛,全栈领域新星创作者。😜
    • 📝 个人主页:馆主阿牛🔥
    • 🎉 支持我:点赞👍+收藏⭐️+留言📝
    • 📣 系列专栏:硬泡 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;
       }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    简易版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))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    示例

    <!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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    在这里插入图片描述
    我的谷歌浏览器物理像素比为1.25
    在这里插入图片描述

    注:
    1.javascript中的立即执行函数:

    (function () {}() 或者 (function(){} ())
    立即执行函数不需要调用就可以执行,第二个小括号可以看做是调用函数。可以给参数,也可以给匿名函数给函数名。

    (function sum(a,b){ return a + b;} (1,2))
    
    • 1

    2.pageshow事件

    下面三种情况都会刷新而面都会触发 load 事件

    1. a 标签的超链接
    2. F5或者刷新按钮(强制刷新)
    3. 前进后退接钮

    但是火狐中,有个特点,有个“往返缓存”,这个缓存中不仅保存着页面数据,还保存了 DOM和JavaScript 的状态;实际上是将整个页面都保存在了内存里
    所以此时后退按钮不能刷新页面。
    此时可以使用 pageshow 事件来触发。这个事件在页面显示时触发,无论是否是来自缓存。在重新加载页面中, pageshow 会在 load 事件触发后触发;根据事件对象中的 persisted 判断是否是缓存中的页面触发的 pageshow 事件,注意这个事件给 window 添加。

    结语

    用这个flexible.js后,你可能需要再装一个cssrem插件,这个插件会自动将你的px转换为rem,提高开发效率,综合来说flexible.js还不错,不用写媒体查询了,且html的fontsize是划分的,一直会随页面大小动态变化,从而实现元素的大小变化。

    如果你觉得博主写的还不错的话,可以关注一下当前专栏,博主会更完这个系列的哦!也欢迎订阅博主的其他好的专栏。

    🏰系列专栏
    👉软磨 css
    👉硬泡 javascript
    👉前端实用小demo
    👉flask框架快速入门

  • 相关阅读:
    基于gRPC编写golang简单C2远控
    zdppy_api 中间件请求原理详解
    python基本类型
    【rar技巧】安装了WinRAR,右键没有压缩选项,怎么回事?
    【设计模式】备忘录模式
    六安RapidSSL泛域名https能保护几个域名
    前端-选中DOM定位源代码
    初识计算机网络
    【STC32G12K128开发板】——STC32G12K128单片机CAN程序
    27-搭建LVS-DR+Nginx高可用模式
  • 原文地址:https://blog.csdn.net/qq_57421630/article/details/125556831