目的
移动端 H5 开发面临的主要挑战是机型碎片化带来的兼容性问题,包括不同操作系统(iOS/Android)、浏览器内核(WebView/第三方浏览器)、屏幕尺寸、硬件性能等差异。本文档旨在沉淀常见兼容性问题的解决方案。
兼容性问题描述
经过专业的第三方兼容性测试平台,测试结果显示,AI 顾问系统存在以下几种兼容性问题:
- iOS11、iOS12、Android8、Android9 机型白屏无法打开页面;
- iOS13,iOS14,Android8,Android9 某些api卡住、报错;
- iOS11,iOS12,iOS13,Android8,Android9,无法复制;
- 华为最新几款机型样式错乱;
问题排查
由于问题有好几类,那么就按照我解决问题的先后顺序进行阐述。
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 问问题不回答
问题定位
- 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);
}
});