必威体育Betway必威体育官网
当前位置:首页 > IT技术

flexible.js源码解析

时间:2019-08-21 00:13:16来源:IT技术作者:seo实验室小编阅读:76次「手机版」
 

flexible

(function flexible (window, document) {
  // 获取页面root根元素 html
  // 跟 document.body 获取的是 页面的 body 元素
  var docEl = document.documentElement
  // window.devicePixelRatio设备像素比
  // 默认为 1
  /**
   * [dpr description]
   * @type {[type]}
   * 设备像素比(device pixel ratio)
   * 设备像素比简称为dpr,其定义了物理像素和设备独立像素的对应关系。
   * 它的值可以按下面的公式计算得到:
   * 设备像素比 = 设备物理像素 / 设备独立像素
   * 设备物理像素是指设备的实际像素
   * 设备独立像素就是指平常我们写 CSS 样式的 px 像素
   * 计算公式: 1px = (dpr)^2dp;
   */
  /**
   * [dpr description]
   * @type {[type]}
   * 基于rem的原理,我们要做的就是: 
   * 针对不同手机屏幕尺寸和dpr动态的改变根节点html的font-size大小(基准值)。
   * 这里我们提取了一个公式(rem表示基准值)
   * rem = document.documentElement.clientwidth * dpr / 10
   */
  /**
   * [dpr description]
   * @type {[type]}
   * 乘以dpr,是因为页面有可能为了实现1px border页面会缩放(scale) 1/dpr 倍(如果没有,dpr=1),。
   * 除以10,是为了取整,方便计算(理论上可以是任何值)
   * 所以就像下面这样,html的font-size可能会:
   * iPhone3gs: 320px / 10 = 32px
   * iphone4/5: 320px * 2 / 10 = 64px
   * iphone6: 375px * 2 / 10 = 75px
   * 对于动态改变根节点html的font-size,我们可以通过css做,也可以通过javascript做。
   */
  var dpr = window.devicePixelRatio || 1

  // adjust body font size
  function setbodyFontSize () {
    if (document.body) {
      // 动态设置body的字体大小
      document.body.style.fontSize = (12 * dpr) + 'px'
    }
    else {
      document.addeventlistener('DOMcontentLoaded', setBodyFontSize)
    }
  }
  // 页面加载时初始化一次
  setBodyFontSize();

  // set 1rem = viewWidth / 10
  /**
   * 如果有一个区块,在psd文件中量出:宽高750×300px的p,
   * 那么如何转换成rem单位呢?
   * 公式如下:
   * rem = px / 基准值;
   * rem = document.documentElement.clientWidth * dpr / 10
   */
  function setRemUnit () {
    var rem = docEl.clientWidth / 10
    docEl.style.fontSize = rem + 'px'
  }

  setRemUnit()

  // reset rem unit on page resize
  window.addEventListener('resize', setRemUnit)
  window.addEventListener('pageshow', function (e) {
    if (e.persisted) {
      setRemUnit()
    }
  })

  // detect 0.5px supports
  // 检测0.5px border
  /**
   * 
   * @param  {Number} dpr >             [description]
   * @return {[type]}     [description]
   * 所以,设计师想要的retina下border: 1px;,其实就是1物理像素宽,
   * 对于css而言,可以认为是border: 0.5px;,
   * 这是retina下(dpr=2)下能显示的最小单位。
   * 然而,无奈并不是所有手机浏览器都能识别border: 0.5px;,
   * iOS7以下,Android等其他系统里,0.5px会被当成为0px处理,
   * 那么如何实现这0.5px呢?
   * 最简单的一个做法就是这样(元素scale):
   * .scale{
   *   position: relative;
   * }
   * .scale:after{
   *   content:"";
   *   position: absolute;
   *   bottom:0px;
   *   left:0px;
   *   right:0px;
   *   border-bottom:1px solid #ddd;
   *   -webkit-transform:scaleY(.5);
   *   -webkit-transform-origin:0 0;
   * }
   * 我们照常写border-bottom: 1px solid #ddd;,
   * 然后通过transform: scaleY(.5)缩小0.5倍来达到0.5px的效果,
   * 但是这样hack实在是不够通用(如:圆角等),写起来也麻烦。
   * 当然还有其他好多hack方法,网上都可以搜索到,但是各有利弊,
   * 这里比较推荐的还是页面scale的方案,是比较通用的,几乎满足所有场景。
   * 对于iphone5(dpr=2),添加如下的meta标签,设置viewport(scale 0.5):
   * <meta name="viewport" content="width=640,initial-scale=0.5,maximum-scale=0.5, Minimum-scale=0.5,user-scalable=no">
   * 这样,页面中的所有的border: 1px都将缩小0.5,从而达到border: 0.5px;的效果。
   */
  if (dpr >= 2) {
    var fakeBody = document.createElement('body')
    var testElement = document.createElement('p')
    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))

相关阅读

分享到:

栏目导航

推荐阅读

热门阅读