移动端页面适配方案

适配原理:

  1. 1rem = font-size
  2. font-size = 视口宽 / 系数
  3. init-scale = 1 / 设备像素比

适配思路:

首先通过JS动态生成meta标签,再通过监听resize事件来获取实时的视口宽,最后通过计算得出HTML元素的font-size。
因为CSS中的rem单位会根据此font-size进行等比变化,所以每次窗口调整时,CSS中使用了rem进行宽高设置的元素也会随之产生缩放效果。但为了防止元素无限缩放而影响视觉,所以限制了maxWidth和minWidth。

关于系数:

直接将视口宽作为font-size通常不便于计算,所以我们选择一个系数来简化数字。将设计稿的宽度与系数相除,得出设计稿原本的font-size,再将设计稿中元素的宽高与该font-size相除,得出元素的rem。

(function () {
  // 使用严格模式
  "use strict";

  // 获取HTML元素、meta标签、设备像素比,设置缩放阈值
  var docEl = document.documentElement,
    viewportEl = document.querySelector('meta[name="viewport"]'),
    dpr = window.devicePixelRatio || 1,
    maxWidth = 540,
    minWidth = 320;

  // 将设备像素比限定在1-3之间
  dpr = dpr >= 3 ? 3 : dpr >= 2 ? 2 : 1;

  // 向HTML增加属性,记录设备像素比、缩放阈值
  docEl.setAttribute("data-dpr", dpr);
  docEl.setAttribute("max-width", maxWidth);
  docEl.setAttribute("min-width", minWidth);

  // 计算缩放值,拼接meta的content
  var scale = 1 / dpr,
    content =
      "width=device-width, initial-scale=" +
      scale +
      ", maximum-scale=" +
      scale +
      ", minimum-scale=" +
      scale +
      ", user-scalable=no";

  // 如果不存在meta标签,则创建后再设置属性
  if (viewportEl) {
    viewportEl.setAttribute("content", content);
  } else {
    viewportEl = document.createElement("meta");
    viewportEl.setAttribute("name", "viewport");
    viewportEl.setAttribute("content", content);
    document.head.appendChild(viewportEl);
  }

  // 页面启动时立刻设置font-size
  setRemUnit();

  // 绑定监听事件,当窗口调整时重新设置font-size
  window.addEventListener("resize", setRemUnit);

  // 设置font-size的函数
  function setRemUnit() {
    // 设定系数
    var ratio = 18.75;
    // 获取视口宽
    var viewWidth = docEl.getBoundingClientRect().width || window.innerWidth;
    // 如果视口宽过大或过小,则进行调整
    if (maxWidth && viewWidth / dpr > maxWidth) {
      viewWidth = maxWidth * dpr;
    } else if (minWidth && viewWidth / dpr < minWidth) {
      viewWidth = minWidth * dpr;
    }
    // 计算font-size
    docEl.style.fontSize = viewWidth / ratio + "px";
  }
})();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值