flexible.js实现移动端适配的原理是什么?

453 阅读3分钟

一、flexible.js 的核心原理

1. 动态 rem 基准值的计算

flexible.js 的核心思想是 基于视口宽度动态设置根元素(html)的 font-size,使页面元素通过 rem 单位实现等比缩放。具体步骤如下:

  • 视口划分:将设备视口宽度(document.documentElement.clientWidth)分为 10 等份,每份为 1rem。例如,视口宽度为 375px 时,1rem = 37.5px。
  • 动态更新:通过监听 resizepageshow 事件,在窗口变化或页面缓存恢复时重新计算 font-size,确保响应式适配。

2. 设备像素比(DPR)与 viewport 缩放

  • DPR 的作用:DPR(Device Pixel Ratio)表示物理像素与 CSS 像素的比值。例如,iPhone 6 的 DPR 为 2,意味着 1 个 CSS 像素对应 2×2 物理像素。
  • viewport 缩放:flexible.js 通过设置 <meta name="viewport">initial-scale1/dpr,将 CSS 像素与物理像素对齐。例如,DPR=2 时,缩放比例为 0.5,避免高清屏下元素显示过小。

3. rem 单位的应用

  • 设计稿转换:设计稿通常以固定宽度(如 750px)制作。开发者将设计稿中的像素值除以基准值(如 75),转换为 rem 单位。例如,设计稿中 150px 的元素对应 2rem(150/75=2)。
  • 自动转换工具:借助 px2rem 等插件,开发阶段可自动将 px 转换为 rem,提升效率。

二、flexible.js 的代码实现解析

1. 代码结构概览

flexible.js 通过立即执行函数初始化,主要包含以下模块:

(function flexible(window, document) {
  // 获取根元素与 DPR
  var docEl = document.documentElement;
  var dpr = window.devicePixelRatio || 1;

  // 设置 body 字体大小
  function setBodyFontSize() { /* ... */ }

  // 计算并设置 rem 基准值
  function setRemUnit() {
    var rem = docEl.clientWidth / 10;
    docEl.style.fontSize = rem + 'px';
  }

  // 监听窗口变化
  window.addEventListener('resize', setRemUnit);

  // 处理 0.5px 边框支持
  if (dpr >= 2) { /* ... */ }
})(window, document);

2. 关键代码解析

  • DPR 获取与缩放设置:通过 window.devicePixelRatio 获取 DPR,动态设置 viewport 的缩放比例,解决高清屏显示问题。
  • rem 动态计算docEl.clientWidth / 10 将视口宽度分为 10 份,确保 rem 基准值随设备宽度变化。
  • 0.5px 边框支持:通过创建测试元素检测浏览器是否支持 0.5px 边框,添加 hairlines 类优化高清屏下的 1px 显示效果。

三、flexible.js 的适配优势与局限性

1. 优势分析

  • 流式布局:通过 rem 实现元素等比缩放,适配不同屏幕尺寸。
  • 高清显示:结合 DPR 调整 viewport 缩放,解决 Retina 屏下的图片模糊与边框过粗问题。
  • 开发便捷:配合自动化工具(如 px2rem),减少手动计算成本。

2. 局限性

  • 维护性下降:需依赖 JavaScript 动态计算,增加运行时开销。
  • 兼容性问题:部分第三方库(如高德地图)可能因 viewport 缩放导致显示异常,需特殊处理。
  • 现代方案替代:CSS3 的 vw/vh 单位及 postcss 插件逐渐成为更轻量的替代方案。

四、flexible.js 的实际应用与优化

1. 设计稿与开发流程

  • 设计稿基准:通常以 750px(二倍图)为标准,1rem=75px,简化计算。
  • 工具链集成:使用 Webpack 的 px2rem-loader 或 Gulp 的 gulp-px3rem 实现自动转换。

2. 常见问题与解决方案

  • 第三方组件适配:如高德地图因 viewport 缩放显示异常时,可通过临时重置 viewport 的 initial-scale 解决。
  • 字体大小调整:设置 bodyfont-size12 * dpr,避免 rem 单位导致字体过小。

五、与其他适配方案的对比

方案原理优点缺点
媒体查询根据设备特性应用不同 CSS 规则简单直观代码冗余,维护成本高
百分比布局相对父元素尺寸定义元素大小无依赖 JavaScript嵌套复杂时计算困难
flexible.js动态 rem + viewport 缩放自适应性强,支持高清屏依赖 JS,需处理第三方兼容性
vw/vh基于视口宽高的 CSS 单位纯 CSS 实现,无运行时开销兼容性需处理(IE9 以下不支持)