目的

移动端 H5 开发面临的主要挑战是机型碎片化带来的兼容性问题,包括不同操作系统(iOS/Android)、浏览器内核(WebView/第三方浏览器)、屏幕尺寸、硬件性能等差异。本文档旨在沉淀常见兼容性问题的解决方案。

兼容性问题描述

经过专业的第三方兼容性测试平台,测试结果显示,AI 顾问系统存在以下几种兼容性问题:

  1. iOS11、iOS12、Android8、Android9 机型白屏无法打开页面;
  2. iOS13,iOS14,Android8,Android9 某些api卡住、报错;
  3. iOS11,iOS12,iOS13,Android8,Android9,无法复制;
  4. 华为最新几款机型样式错乱;

问题排查

由于问题有好几类,那么就按照我解决问题的先后顺序进行阐述。

1. 白屏问题

1.1 问题定位 因为 iOS11、iOS12、Android8、Android9 都属于比较老的系统,直接白屏 1.2 解决方案 由于上面已经定位到了问题(此时应该不能叫做定位到问题,准确的说是找到了怀疑的点),那么就开始更改打包配置,使其打包出来的代码更加具有兼容性,比如打包到 es5 版本,所以更改 vite 打包配置,增加如下配置:

import legacy from '@vitejs/plugin-legacy'
 
export default defineConfig({
    ...,
    build: {
        target: 'es5'
    },
    ...,
    plugins: [
      ...,
      legacy({
        targets: [
          "ie >= 11",
          "iOS >= 10",
          "> 1%",
          "last 2 versions",
          "not ie <= 8",
        ],
      }),
    ]
})

2. 问问题不回答

iOS13,iOS14,Android8,Android9 问问题不回答

问题定位

  1. TextDecoderStream 某些浏览器都不支持

解决方案:

安装依赖 npm i text-decoder

async function processStream(response, callback) {
  const reader = response.body.getReader();
  const decoder = new TextDecoder();
  let partialChunk = '';
 
  while (true) {
    const { done, value } = await reader.read();
    if (done) {
      if (partialChunk) callback(partialChunk);
      break;
    }
 
    const text = partialChunk + decoder.decode(value, { stream: true });
    const lines = text.split('\n');
 
    partialChunk = lines.pop() || '';
    lines.forEach(line => callback(line));
  }
}

3. 复制失败

问题定位

新的 API:navigator.clipboard.writeText,老旧浏览器并不支持这个 API。

解决方案

使用 clipboard 这个库:

import ClipboardJS from 'clipboard'
 
const initCopyMsg = () => {
  copyCode = new ClipboardJS('.copy-text-icon')
  copyCode.on('success', (e: any) => {
    ElMessage.success('复制成功')
    e.clearSelection()
  })
  copyCode.on('error', (e: any) => {
    ElMessage.error('复制失败')
    e.clearSelection()
  })
}
 
onMounted(() => {
  initCopyMsg()
})

4. 华为最新几款机型样式错乱

其它机型都没样式问题,而只有华为手机有问题。由于鸿蒙系统还比较年轻,它的生态是比较差的,所以就会导致样式的解析方面有问题。

问题定位

经过查阅资料得知鸿蒙系统和安卓的区别,鸿蒙系统大部分都和 Android 系统一样,有细微的差别,表现在样式问题上就是在于 webview 层,鸿蒙多加了一些自己的解析规则,多少是显得有些鸡肋的。

解决方案

css 部分

<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta
  name="viewport"
  content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover"
/>
body {
  -webkit-overflow-scrolling: touch;
  overflow-scrolling: touch;
}

再增加 autoprefixer 配置。

js 部分

window.addEventListener("resize", () => {
  if (
    document.activeElement.tagName === "INPUT" ||
    document.activeElement.tagName === "TEXTAREA"
  ) {
    setTimeout(() => {
      window.scrollTo(0, document.body.scrollHeight);
    }, 300);
  }
});