Skip to content

Latest commit

 

History

History
82 lines (63 loc) · 4.11 KB

flexible.js 源码解读.md

File metadata and controls

82 lines (63 loc) · 4.11 KB

flexible.js 源码解读

flexible.js 是移动端的一种使用 rem 适配方案。

源码相对简单,需要知道的前置知识:

  • 使用 rem 作为单位,因为 rem 是一个相对单位,它相对于根元素的 font-size,页面元素的大小计算都与根元素进行换算。(默认浏览器的大小 16px)
  • window.devicePixelRatio 它将返回当前显示设备的物理像素分辨率与 CSS 像素分辨率之比,也就是设备像素比(DPR)。通过设备屏幕的 DPR,自动设置最合适当前设备的高清缩放。

源码地址

这里需要解读的代码量相对较少,我直接在代码内进行注释:

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

  // 调整 body 字体大小,也就是子元素的默认字体大小都继承自 body
  function setBodyFontSize() {
    if (document.body) {
      document.body.style.fontSize = 12 * dpr + 'px'
    } else {
      document.addEventListener('DOMContentLoaded', setBodyFontSize)
    }
  }

  setBodyFontSize()

  // set 1rem = viewWidth / 10
  // 也就是 1rem 等于视口/屏幕可视区域宽度的 1/10,将宽度分割为十等分
  // 例如:iphone 6 的屏幕宽度为 375px,因此 375 / 10 = 37.5px = 1rem
  function setRemUnit() {
    var rem = docEl.clientWidth / 10
    docEl.style.fontSize = rem + 'px'
  }

  setRemUnit()

  // 页面调整时重置 rem
  window.addEventListener('resize', setRemUnit)
  // pageshow 事件在每次加载页面时触发(包括后退/前进按钮操作,同时也会在 onload 事件触发后初始化页面时触发)
  window.addEventListener('pageshow', function (e) {
    // persisted 属性表示网页是否是来自缓存
    if (e.persisted) {
      setRemUnit()
    }
  })

  // 检测是否支持 0.5px,解决 1px 在高清屏多像素问题
  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)

相信整体看下来,您已经清楚了 flexible.js 的工作方式。

另外,如果使用到了 rem 适配方案,推荐阅读手机端页面自适应解决方案—rem 布局进阶版(附源码示例)

最后

推荐阅读一下有关 CSS 单位的知识:CSS 单位及其需要注意的地方

如今,视口单位已经得到了很好的支持,且能很好的解决横屏问题,比较推荐使用。

以下在推荐几篇移动端适配相关的文章: