返回 blog
2022年10月14日
2 分钟阅读

移动端适配

viewport 视窗

首先需要配置html中的meta标签:

<meta content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no,viewport-fit=cover" name="viewport" />
  • width=device-width 网页宽度等于设备宽度
  • initial-scale=1 初始缩放为1
  • minimum-scale=1 最小缩放1
  • maximum-scale=1.0 最大缩放1
  • user-scalable=no 禁止用户缩放
  • viewport-fit=cover 相当于background-size, 网页如何适应视窗,cover的话就是网页占满视窗

设备像素比dpr、 物理像素px

其实几倍屏你不用关注,逻辑像素和物理像素的比列,浏览器会给你处理,你只需要关注,你手上的psd图的像素,和具体css中px的长度就行。然后再来转换就行了。几倍屏是厂商的问题,现在基本都3倍屏但是很多还是375px,所以不影响。

rem 相对根字体大小

如: 根字体 font-size: 32px => 1rem: 32px

所以处理不同像素的屏幕,使用rem来布局css比较方便,px是固定的,在每个屏幕上显示的大小一样,那么或许iphone6上显示合适,到ipad上就小了

具体的配置方式:

(function () {
  const ipadProWidth = 1024
  const UIWidth = 375
  function resize() {
    let windowWidth = window.innerWidth
    if (windowWidth > window.screen.width) {
      // window.requestAnimationFrame(resize); 当windowWidth > window.screen.width 时,无限循环resize了
      return;
    } else {
      if (windowWidth > ipadProWidth) {
        windowWidth = ipadProWidth
      }
      document.documentElement.style.fontSize = `${windowWidth / UIWidth  }px`
    }
  }

  resize()

  window.addEventListener('resize', resize)
  window.addEventListener('pageshow', function (e) {
    if (e.persisted) {
      // e.persisted 判断网页是否后退进入
      resize()
    }
  })
})(window, document)

当上面这个js执行完之后, 可以看到,在375分辨率的屏幕下, image.png 那么在750的分辨率下,font-size肯定是2px了 image.png 此时,我们还未配置 pxtorem, 但是也可以使用。假设设计给到的设计图,是以375为基准的,那就正好,我们只需要把设计图上的 100px 写成 100rem 即可。那假设设计给的设计图是以750为基准的,我们可以把上面的js中的 UIWidth 改成 750 即可。

那有的同学不想写rem,想在css里面写px,因为习惯了嘛,那也可以,在webpack中配置 post-pxtorem 即可(或在postcss.config.js中配置) 步骤如下:

  1. 安装插件
  2. 引入插件,并配置
{
  {
    [
      require('postcss-pxtorem')({
         rootValue: 1,  
         propWhiteList: [],
         minPixelValue: 2
       })
    ]
  }
}

其中最主要的是 rootValue 字段:根字体的大小, 从上面的js中,我们算出来,在期望的375px中,根字体大小为1。如果你觉得 font-size:1px 看起来很丑,也可以设置成其他大小,比如 rootValue: 16 , 对应的修改resize方法

 document.documentElement.style.fontSize = `${ww * 16 / UIWidth  }px`

结果: image.png 照样的,在css文件中写成设计图上的像素即可,不需要写rem,也不需要翻倍之类的

优化

最好是在html标签上给个初始化默认的font-size,避免内容跳动。比如你期望 font-size:16px

<html style="font-size: 16px;"></html>

window.innerWidth 跟 window.screen.width 的区别

window.innerWidth 返回屏幕的像素宽度。window.innerWidth >= window.screen.width,因为机型的物理分辨率不可能达到很高(现在物理技术就这样)。 window.screen.width 返回屏幕的物理分辨率宽。如:iphonex的 window.screen.width 永远是375。每个机型的window.screen.width是永远固定不变的。

引申知识

back-forward cache

“往返缓存”。可以在用户使用浏览器的“后退”和“前进”按钮时加快页面的转换速度。这个缓存不仅保存页面数据,还保存了DOM和JS的状态,实际上是将整个页面都保存在内存里。如果页面位于bfcache中,那么再次打开该页面就不会触发onload事件。适用于多页面网页,单页面网页不适用。

pageshow事件

这个事件在用户浏览网页时触发,pageshow 事件类似于 onload 事件,onload 事件在页面第一次加载时触发, pageshow 事件在每次加载页面时触发,即 onload 事件在页面从浏览器缓存中读取时不触发

pagehide事件

该事件会在用户离开网页时触发。离开网页有多种方式。如点击一个链接,刷新页面,提交表单,关闭浏览器等。pagehide 事件有时可以替代 unload事件,但 unload 事件触发后无法缓存页面。

persisted属性

pageshow 事件和 pagehide 事件的event对象还包含一个名为 persisted 的布尔值属性。 对于pageshow事件,如果页面是从bfcache中加载的,则这个属性的值为true;否则,这个属性的值为false。 对于pagehide事件,如果页面在卸载之后被保存在bfcache中,则这个属性的值为true;否则,这个属性的值为false。

当然还有一些不太通用的响应式单位

  • vw vh vmin vmax
  • 百分比

这两种单位,在某些情况下是很好用的,比如一行四个 宽度就可以设置成百分比