Skip to content
文章目录

常见问题解决方案

js 获取设备 dpr

js
const dpr = devicePixelRatio >= 3 ? 3 : devicePixelRatio >= 2 ? 2 : 1
document.documentElement.setAttribute('data-dpr', dpr)

ios 100vh 问题

原因: safari 浏览器的 100vh 包含地址栏和底部栏的高度,而其他浏览器只是视口高度

解决方案

方案一: vh-check 插件

pnpm install vh-check
js
import vhCheck from 'vh-check'
// 设置一个css变量
vhCheck('brwoser-address-bar')
css
height: calc(100vh - var(--browser-address-bar, 0px));

calc(100vh - var(--browser-address-bar, 0px)) 表示 100vh 的实际高度

vh-check 文档

方案二: 使用 js 动态改变盒子高度

使用 js 动态改变盒子高度,即使用window.innerHeight来获取实际的屏幕高度,然后赋值给需要改变的元素 即xxxx.style.height = window.innerHeight +'px'

屏幕适配问题

不同 dpr 设备使用不同的多倍图

1px 边框问题

1px 问题说明

先说个适配的过程:

在宽100米,长100米画布正常显示的图形,要在宽长都是50米的画布内正常显示,要怎么做?
必然是将原本100米画布内的图形也都按比例缩小2倍,就正常了

移动端屏幕适配也是这个原理。记住上面的例子

设计师的设计稿如果是 750px,在上面设置了一个 1px 宽度的元素。那么换成 375 的屏幕,是不是原来 1px 的宽度,就要缩小为 0.5px。

而有些浏览器不支持显示小于 1px 的像素,所有小于 1px 的像素,全部按照 1px 显示,那么此时,如果设计师拿着 375 分辨率的设备看,就会觉得这里应该是 0.5px 的宽度,而实际看到的是 1px,他就会觉得宽了。

给个图例说明

html
<!--

@author: pan
@createDate: 2022-12-06 16:10
-->
<script setup lang="ts">
  import { Toast } from 'vant'

  //@ts-ignore
  const dpr = devicePixelRatio >= 3 ? 3 : devicePixelRatio >= 2 ? 2 : 1
</script>

<template>
  <div>
    <dl class="a comm">
      <dt>正方形A</dt>
      <dd>border-width:0.5px</dd>
    </dl>
    <dl class="b comm">
      <dt>正方形B</dt>
      <dd>border-width:1px</dd>
    </dl>
  </div>
</template>

<style lang="scss" scoped>
  dd {
    margin: 0;
    font-size: 20px;
  }
  .comm {
    width: 200px;
    height: 200px;
    margin: auto auto 10px auto;
    background-color: #f3f3f3;
    border-radius: 5px;
    text-align: center;
    display: flex;
    flex-direction: column;
    justify-content: center;
  }
  .a {
    /* prettier-ignore */
    border: 0.5PX solid red;
  }
  .b {
    /* prettier-ignore */
    border: 1PX solid red;
  }
</style>

上面的代码了两个正方形:正方形 A 的边框宽度设置成了 0.5px,正方形 B 的边框宽度设置成了 1px。

下面这张图是在普通 PC 电脑上看到的效果,该设备的浏览器不支持显示小于 1px 的像素,所有 0.5px 和 1px 的边框,都被显示成了 1px, 所以两个正方形的边框粗细,完全没区别

再往下这张图是在手机上看到的效果,该设备的浏览器支持显示小于 1px 像素,所以 0.5px 就是按 0.5px 显示的,1px 就是按 1px 显示的(可能由于图片被放大的原因,看着不明显,你可以用上面的代码,运行之后,分别在你手机和 PC 上查看)

click 点击 300 毫秒延迟问题

原因

移动端要判断是否是双击,所以单击之后不能够立刻触发 click,要等 300ms,直到确认不是双击了才触发 click。所以就导致了 click 有延迟。

解决方案

html
<meta name="viewport" content="width=device-width, initial-scale=1.0" />

注意: 采用此解决方案,将不会再有浏览器默认的双击缩放功能

参考文章

关于 h5 端点击事件 300ms 延迟问题

关闭 IOS 键盘首字母大写

html
<input type="text" autocapitalize="false" />

让 Chrome 支持小于 12px 的文字

通过 transform: scale(x) 实现

css
div {
  font-size: 100px;
}
div span {
  display: inline-block;
  /* 
  这个span会继承div的字体大小,这里再设置为缩放为0.1倍,那就是10px。
  注意:这里缩放的是盒子的大小,来间接达到显示小字体大小的效果,
  实际并不是直接控制了字体大小。因此实际还是要避免设计稿中出现小于12px的字体大小
  */
  transform: scale(0.1);
}

去除 IOS 中被触摸元素的半透明遮罩

css
button,
a,
textarea,
input {
  tap-highlight-color: rgba(0, 0, 0, 0);
  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}

ios 滚动不流畅问题

禁止缩放

禁止 IOS & Android 用户选中文字

css
html,
body {
  user-select: none;
  -webkit-user-select: none;
}

ios 浏览器不支持 yyyy-MM-dd HH:mm:ss 或 yyyy-MM-dd 格式对 Date 进行初始化

使用第三方工具(如:dayjs)进行日期对象和字符串的相互转换

禁止 ios 长按触发系统菜单,禁止 IOS & Android 长按时下载图片

css
html,
body {
  touch-callout: none;
  -webkit-touch-callout: none;
}

安全区适配

滚动穿透

如何调试

不同终端判断

参考资料

touch-action

移动端双指缩放图片 JS 事件的实践心得

js 实现双指缩放

document.activeElement 的使用

移动端兼容性问题及解决方案汇总

从零单排番外篇:给 JavaScript 加点“类型”

从零单排:使用 pnpm 创建 monorepo