移动端REM适配的基本实现

Eleven
  REM是移动端屏幕适配的常见方案,可以选用淘宝开源的flexible,只是用起来稍微有一点麻烦,我一般采用更加简洁的方案,动态去计算html跟标签的font-size,监听屏幕的尺寸变化及时响应,兼顾用户修改系统字体时的处理等其它细节。
  采用VW方案去适配也是一个好办法,只是兼容性不太好,需要根据具体场景去选择。

开始使用

  1. 压缩后,放置到 head 标签的尾部,直接 script 标签嵌入,保证最先执行,避免用户感知到页面跳动;
  2. 建议加如下代码,将默认字体大小重置为16px,避免在js未执行时,样式、字体混乱:

    html,
    body {
      font-size: 16px;
    }
  3. 字体需不需要使用 rem 单位?看产品、设计师的定位吧,通常建议不要对字体使用 rem 单位(牵扯到布局还是应该采用rem单位),尤其是大段的文章;

代码

<script>
/*
 * REM适配:
 *   1.动态设置html标签font-size;
 *   2.动态设置html标签data-dpr、data-img-rate属性;
 *   3.用户调整系统字体大小时,避免页面样式错乱;
 *   4.计算公式:
 *      750的设计稿,量图的大小 / 100 => rem数值
 */

(function (document, window) {
  var docEl = document.documentElement,
    user_webset_font, // 用户设置的浏览器的字体大小(兼容ie)
    rate = 1, // 用户设置的字体大小和默认16px的比例系数
    resizeEvent = 'orientationchange' in window ? 'orientationchange' : 'resize';

  if (docEl.currentStyle) {
    user_webset_font = docEl.currentStyle['fontSize'];
  } else {
    user_webset_font = getComputedStyle(docEl, false)['fontSize'];
  }

  // 用户调整系统字体大小或浏览器字体大小时,需要做兼容。
  rate = parseFloat(user_webset_font) / 16;

  /**
   * 设置html标签font-size
   */
  var resetRootFontSize = function () {
    var clientWidth = docEl.clientWidth;

    if (!clientWidth) return;

    if (clientWidth >= 1080) {
      docEl.style.fontSize = 200 / rate + 'px';
    } else {
      // 750设计稿
      docEl.style.fontSize = 100 * ( clientWidth / 750 ) / rate + 'px';
      // 375设计稿
      // docEl.style.fontSize = 100 * (clientWidth / 375) / rate + 'px';
    }
  }

  /**
   * 设置html的data-dpr/data-img属性(供选用而设置)。
   */
  var resetDpr = function () {
    if (!window.devicePixelRatio) return;
    // 屏幕像素比大于等于3,采用3倍图,否则使用2倍图.
    var imgRate = window.devicePixelRatio >= 3 ? 3 : 2;

    docEl.setAttribute('data-dpr', window.devicePixelRatio);
    docEl.setAttribute('data-img-rate', imgRate);
  }

  // 直接执行,不放到 DOMContentLoaded 事件执行,否则页面能感知到跳动
  resetRootFontSize();
  resetDpr();

  if (!window.addEventListener) return;
  window.addEventListener(resizeEvent, function () {
    resetRootFontSize();
    resetDpr();
  }, false)
})(document, window);
</script>
阅读 1.4k
334 声望
56 粉丝
0 条评论
334 声望
56 粉丝
文章目录
宣传栏