移动端适配之rem.js

移动端网页适配是一个麻烦事, 常见做法有媒体查询, js控制等.
媒体查询个人感觉比较冗余, 可少量使用, 偏爱于js来控制.

下面是我自己总结的rem.js:

(function(doc, win) {

  // html元素字体
  // 这里基础字体设置为10在uc, WX上没效果,  不知道为什么
  // 设置为10时, dpr=1的手机, 宽度360, 计算出来html的字体大小为5px, 可能是字体太小了
  // 尽量设置大一些, 这样避免12px字体大小的限制
  var _rootFontSize = window._rootFontSize || 25;

  // 默认不支持缩放
  var _remMetaScalable = typeof window._remMetaScalable === 'undefined' 
    ? false 
    : !!window._remMetaScalable;

  var docEl = doc.documentElement,
    isIOS = navigator.userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/),

    // 只针对IOS设备
    dpr = isIOS ? Math.min(win.devicePixelRatio, 3) : 1,

    // 计算缩放比
    scale = 1 / dpr,

    // 检测支持的"缩放"事件
    resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize';
  docEl.dataset.dpr = dpr;

  // 被iframe引用时,禁止缩放
  dpr = window.top === window.self ? dpr : 1;

  var metaEl = doc.createElement('meta');
  metaEl.name = 'viewport';
  var metaElContent = 'width=device-width, ';

  // 支持缩放
  if (_remMetaScalable) {
    metaElContent += 'initial-scale=' + scale;
  } else {
    metaElContent += (
      'initial-scale=' + scale 
      + ',maximum-scale=' + scale 
      + ', minimum-scale=' + scale 
      + ', user-scalable=no');
  }
  metaEl.content = metaElContent;
  docEl.firstElementChild.appendChild(metaEl);

  // 缩放/旋转设备检测函数
  var recalc = function() {
    var width = docEl.clientWidth;

    // 750为设计用的宽度, 比如它以iphone6标准(宽750)
    // 此时, 按照设计稿的尺寸写就可以了
    // 如: 设计稿为100px, 那么就写4rem(100 / 25), 25是自己设置的
    // 也可以设置成100, 这样就写100px就写1rem
    docEl.style.fontSize = _rootFontSize * (width / 750) + 'px';
  };
  recalc();

  if (!doc.addEventListener) return;
  win.addEventListener(resizeEvt, recalc, false);
})(document, window);

使用示例:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport"
    content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
<title>rem</title>
<style type="text/css">
  .c1 {
    border: 2px solid black;
    font-size: 32px;
  }

  .c2 {
    border: 2px solid black;
    font-size: 1.28rem;
  }

  .c3 {
    border: 1px solid black;
    font-size: 1.28rem;
  }
</style>
<script type="text/javascript" src="rem.js"></script>
</head>

<body>
  <pre class="c1">
  .c1 {
    border: 2px solid black;
    font-size: 32px;
  }
  </pre>
  <pre class="c2">
  .c2 {
    border: 2px solid black;
    font-size: 1.28rem;
  }
  </pre>
  <pre class="c3">
  .c3 {
    border: 1px solid black;
    font-size: 1.28rem;
  }    
  </pre>
</body>
</html>

实际效果:
rem.js测试效果

可以看出:

在DPR为1时, 其实用什么都可以的, 也就是我们正常在pc页面上的写法.
在DPR为2时:

  1. 不使用rem.js, 实际显示效果就会是我们写的2倍.
    这也就是为什么我们写的1px的边框在iPhone手机上常常看起来比较粗的原因.
  2. 使用rem.js, 效果才是我们预期的.

: 谷歌浏览器如何添加自定义模拟设备
谷歌浏览器如何添加自定义模拟设备


总结:
使用这里的rem.js后, 可以不用媒体查询,
方便全局控制, 而且还可以解决iPhone下”1px边框的问题”.
如果再结合postcss-pxtorem, sublime cssrem等插件的协助,
就可以像pc上一样以px作为单位来书写, 非常方便.

欢迎补充指正!

猜你喜欢

转载自blog.csdn.net/butterfly5211314/article/details/79871805