loading

移动端适配

收集的一些优化方法,项目中要多尝试 🤔🤔🤔

相对于PC端来说,移动端设备分辨率百花齐放,千奇百怪,对于每一个开发者来说,移动端适配是我们进行移动端开发第一个需要面对的问题。

在移动端我们经常可以在head标签中看到这段代码:

<meta name='viewport' content='width=device-width,initial-scale=1,user-scale=no' />
1

meta的设置其实就是对网页的宽度和浏览器窗口的宽度进行设置。

  • width=device-width表示页面宽度与设备视口宽度一致
  • initial-scale=1表示页面宽度和网页宽度与设备视口宽度的初始缩放比例
  • user-scale=no禁止缩放

# rem方案

rem 是相对于根元素 html 的 font-size 来做计算。通常在页面初始化时加载时通过对document.documentElement.style.fontSize 设置来实现。实现代码如下:

;(function (doc, win) {
   let docEl = doc.documentElement;
   //考虑以及兼容了 屏幕旋转的事件
   let resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize';
   let recalc = function () {
     var clientWidth = docEl.clientWidth;
     if (!clientWidth) return;
     if (clientWidth >= 750) {
       docEl.style.fontSize = '100px';
     } else {
       docEl.style.fontSize = 100 * (clientWidth / 750) + 'px';
     }
   };
   if (!doc.addEventListener) return;
   win.addEventListener(resizeEvt, recalc, false); // 屏幕大小以及旋转变化自适应
   doc.addEventListener('DOMContentLoaded', recalc, false); // 页面初次打开自适应
   recalc();
})(document, window);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

上面代码中,clientWidth为750(iphone6)时,1rem=100px。一般设计图的宽度为750px,加入测量尺寸为100px,css代码中可以直接写1rem。

# 1px边框

  • 屏幕的1px(每个物理像素)和css中写的1px之间是有区别的,在普通屏幕下,css的1px对应1物理像素,在2倍屏、3倍屏下1px分别对应2物理像素、3物理像素。

  • dpr(屏幕像素比,可以理解为每px用多少物理像素显示) = 2就是2倍屏。同样是宽为350px的设备,普通屏看起来正常,2倍屏看起来线条就很粗。如果需要全局都能画出1px的线呢?我们只要保证让1px始终只占1个物理像素就行了。通常通过改变meta标签的viewport的initial-scale值实现。

  • 对于2倍屏设置initial-scale=0.5,对于3倍屏设置initial-scale=0.33,因此,我们还需要在网页渲染前用脚本通过window.devicePixelRatio获取dpr,然后将initial-scale设置为 1/dpr。

(function () {
  function resetViewPort() {
    var viewport = document.querySelector('meta[name = viewport]');
    if (!viewport) {
      viewport = document.createElement("meta");
      var head = document.querySelector("head");
      head.insertBefore(viewport, head.firstChild);
    }
    var ratio = window.devicePixelRatio || 1;
    var content = 'width=device-width,initial-scale=' + Math.round(100 / ratio) / 100 + ',maximum-scale=1,user-scalable=no';
    viewport.setAttribute("content", content);
  };
  window.addEventListener('DOMContentLoaded', resetViewPort);
})()
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# px自动转rem

# 完整配置

;(function (doc, win) {
  let docEl = doc.documentElement;
  //考虑以及兼容了 屏幕旋转的事件
  let resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize';
  let recalc = function () {
    var clientWidth = docEl.clientWidth;
    if (!clientWidth) return;
    resetViewPort();
    if (clientWidth >= 750) {
      docEl.style.fontSize = '100px';
    } else {
      docEl.style.fontSize = 100 * (clientWidth / 750) + 'px';
    }
  };
  let resetViewPort = function () {
    var viewport = document.querySelector('meta[name = viewport]');
    if (!viewport) {
      viewport = document.createElement("meta");
      var head = document.querySelector("head");
      head.insertBefore(viewport, head.firstChild);
    }
    var ratio = window.devicePixelRatio || 1;
    var content = 'width=device-width,initial-scale=' + Math.round(100 / ratio) / 100 + ',maximum-scale=1,user-scalable=no';
    viewport.setAttribute("content", content);
  };
  if (!doc.addEventListener) return;
  win.addEventListener(resizeEvt, recalc, false); // 屏幕大小以及旋转变化自适应
  doc.addEventListener('DOMContentLoaded', recalc, false); // 页面初次打开自适应
  recalc();
})(document, window);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
最近更新时间: 2021/06/17 10:13:36
最近更新
01
2023/07/03 00:00:00
02
2023/04/22 00:00:00
03
2023/02/16 00:00:00