深入探究flexiblejs

一、flexiblejs原理

flexiblejs是一款基于淘宝移动端适配方案的自适应方案,在移动端设备中,通过重新计算文档的根节点字体大小,实现了不同屏幕尺寸下的页面自适应。

具体来说,它通过以下几个步骤来实现自适应:

  1. 获取设备的屏幕宽度,并计算出font-size的大小。
  2. (function(win, lib) {
        var timer,
            doc = win.document,
            docElem = doc.documentElement,
            vpMeta = doc.querySelector('meta[name="viewport"]'),
            flexMeta = doc.querySelector('meta[name="flexible"]'),
            dpr = 0,
            scale = 0,
            tid;
    
    // 获取设备CSS像素比
        if (vpMeta) {
            console.warn('将根据已有的meta标签来设置缩放比例');
            var initial = vpMeta.getAttribute('content').match(/initial\-scale=([\d\.]+)/);
            if (initial) {
                scale = parseFloat(initial[1]);
                dpr = parseInt(1 / scale);
            }
        }
    
    // 获取flexible配置信息
        if (flexMeta) {
            var flex = flexMeta.getAttribute('content');
            if (flex) {
                var arr = flex.split(';');
                for (var i = 0; i  max) {
                                    dpr = max;
                                    scale = parseFloat((1 / dpr).toFixed(2));
                                }
                                break;
                            case 'design-width':
                                lib.designWidth = parseFloat(item[1]);
                                break;
                            case 'maxWidth':
                                lib.maxWidth = parseFloat(item[1]);
                                break;
                            case 'disableScale':
                                lib.disableScale = item[1] === 'true';
                                break;
                        }
                    }
                }
            }
        }
    
    // 设置data-dpr属性,方便调试
        docElem.setAttribute('data-dpr', dpr);
    
    // 设置viewport
        if (!vpMeta) {
            vpMeta = doc.createElement('meta');
            vpMeta.setAttribute('name', 'viewport');
            vpMeta.setAttribute('content', 'width=device-width, initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');
            if (docElem.firstElementChild) {
                docElem.firstElementChild.appendChild(vpMeta);
            } else {
                var div = doc.createElement('div');
                div.appendChild(vpMeta);
                doc.write(div.innerHTML);
            }
        } else {
            vpMeta.setAttribute('content', 'width=device-width, initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');
        }
    
    // 设置根字体大小
        function refreshRem() {
            var width = docElem.getBoundingClientRect().width;
            if (lib.maxWidth && (width / dpr > lib.maxWidth)) {
                width = lib.maxWidth * dpr;
            }
            var rem = width / 10;
            docElem.style.fontSize = rem + 'px';
            lib.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);
    
        refreshRem();
    
        lib.dpr = win.dpr = dpr;
        lib.refreshRem = refreshRem;
        lib.rem2px = function(d) {
            var val = parseFloat(d) * this.rem;
            if (typeof d === 'string' && d.match(/rem$/)) {
                val += 'px';
            }
            return val;
        };
        lib.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'] = {}));
    
  3. 设置viewport的meta标签。
  4. vpMeta.setAttribute('content', 'width=device-width, initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');
    
  5. 设置根字体大小。
  6. docElem.style.fontSize = rem + 'px';
    

二、flexiblejs还有人用吗

随着CSS3的普及,越来越多的开发者开始使用CSS3的媒体查询来实现移动端适配。不过,flexiblejs依然是一款优秀的适配方案,尤其适用于需要兼容旧设备的场景。它的优点包括:

  • 无需在每个页面都进行像素单位的转换,大大提高了开发效率。
  • 支持多种分辨率的设备,页面表现更加一致。
  • 支持rem和px单位的自由切换。
  • 灵活,可以根据需求进行定制。

三、flexiblejs引入

在引入flexiblejs之前,需要在head区域加入viewport的meta标签,并去除默认的缩放限制。


然后,在任意一个JS文件中添加以下代码即可:

(function(win, lib) {
    // ...
})(window, window['lib'] || (window['lib'] = {}));

四、flexiblejs不用了

在使用flexiblejs的过程中,我们也要注意一些需要避免的坑,比如:

  • 尽量避免使用图片和视频等非常大的元素。
  • 避免使用过多的字体样式。
  • 尽量遵循设计规范,避免过多使用宽度百分比。
  • 不要在样式表中使用!important,这样会破坏原本的比例关系。

如果你已经要废弃flexiblejs,可以单独在head区域删除相关的meta标签,然后手动设置根字体大小即可。

html {
    font-size: 16px;
}

五、flexiblejs的缺点

虽然flexiblejs是一款非常优秀的移动端适配方案,但也有一些缺点:

  • 有时候会出现模糊的问题。
  • 使用rem作为单位,在某些场景下会显得不够灵活。
  • 对于在Android4.4以下的系统上,可能会遇到一些兼容性问题。

六、flexiblejs替代方案选取

除了flexiblejs以外,还有一些其他的移动端适配方案,比如:

  • 媒体查询:这是最传统的适配方案,通过CSS3的媒体查询来适配不同尺寸的设备。
  • Bootstrap:这是一款非常流行的响应式框架,可以支持更丰富的页面布局效果。
  • Viewport units:除了rem以外,还可以使用vw和vh等单位来实现自适应。

综合性能、兼容性和使用难度等因素,可以按照不同项目的需要来选择适当的方案。

原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/270044.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
小蓝小蓝
上一篇 2024-12-16 13:35
下一篇 2024-12-16 13:35

相关推荐

  • 深入解析Vue3 defineExpose

    Vue 3在开发过程中引入了新的API `defineExpose`。在以前的版本中,我们经常使用 `$attrs` 和` $listeners` 实现父组件与子组件之间的通信,但…

    编程 2025-04-25
  • 深入理解byte转int

    一、字节与比特 在讨论byte转int之前,我们需要了解字节和比特的概念。字节是计算机存储单位的一种,通常表示8个比特(bit),即1字节=8比特。比特是计算机中最小的数据单位,是…

    编程 2025-04-25
  • 深入理解Flutter StreamBuilder

    一、什么是Flutter StreamBuilder? Flutter StreamBuilder是Flutter框架中的一个内置小部件,它可以监测数据流(Stream)中数据的变…

    编程 2025-04-25
  • 深入探讨OpenCV版本

    OpenCV是一个用于计算机视觉应用程序的开源库。它是由英特尔公司创建的,现已由Willow Garage管理。OpenCV旨在提供一个易于使用的计算机视觉和机器学习基础架构,以实…

    编程 2025-04-25
  • 深入了解scala-maven-plugin

    一、简介 Scala-maven-plugin 是一个创造和管理 Scala 项目的maven插件,它可以自动生成基本项目结构、依赖配置、Scala文件等。使用它可以使我们专注于代…

    编程 2025-04-25
  • 深入了解LaTeX的脚注(latexfootnote)

    一、基本介绍 LaTeX作为一种排版软件,具有各种各样的功能,其中脚注(footnote)是一个十分重要的功能之一。在LaTeX中,脚注是用命令latexfootnote来实现的。…

    编程 2025-04-25
  • 深入理解Python字符串r

    一、r字符串的基本概念 r字符串(raw字符串)是指在Python中,以字母r为前缀的字符串。r字符串中的反斜杠(\)不会被转义,而是被当作普通字符处理,这使得r字符串可以非常方便…

    编程 2025-04-25
  • 深入了解Python包

    一、包的概念 Python中一个程序就是一个模块,而一个模块可以引入另一个模块,这样就形成了包。包就是有多个模块组成的一个大模块,也可以看做是一个文件夹。包可以有效地组织代码和数据…

    编程 2025-04-25
  • 深入探讨冯诺依曼原理

    一、原理概述 冯诺依曼原理,又称“存储程序控制原理”,是指计算机的程序和数据都存储在同一个存储器中,并且通过一个统一的总线来传输数据。这个原理的提出,是计算机科学发展中的重大进展,…

    编程 2025-04-25
  • 深入剖析MapStruct未生成实现类问题

    一、MapStruct简介 MapStruct是一个Java bean映射器,它通过注解和代码生成来在Java bean之间转换成本类代码,实现类型安全,简单而不失灵活。 作为一个…

    编程 2025-04-25

发表回复

登录后才能评论