背景
功能开发完进入二轮测试没什么bug了,前端内心正爽...
- 测试:"有几个兼容问题,麻烦你看下"
- 前端: "好的,机器都放这吧",内心一阵忧伤...
以此文记录自己遇到的兼容坑,避免再次踩坑 or 下次再见时能快速定位~
问题列表
1.移动端内webview相关
1-1.软键盘弹出遮挡input输入框问题
- 问题现象:
- 页面上有多个input框且靠近页面底部位置,当用户使用input输入时会吊起系统自带的软键盘,此时会有两种情况
- case 1: 大部分ios & android中,软键盘自动顶起页面的输入框,用户输入不被遮挡
- case 2: 少部分安卓机型,软键盘直接遮盖页面底部,用户输入被遮挡
- 页面上有多个input框且靠近页面底部位置,当用户使用input输入时会吊起系统自带的软键盘,此时会有两种情况
- 解决方法:
- 在安卓端内,则监听focus & blur事件,当页面上有focus事件,则表示用户正在输入,软键盘自动弹出
- 正常不会遮挡输入框的case1中,window.innerHeight会比初始状态下减小(因为键盘弹起)
- 因此,focus事件中检测window.innerHeight是否减小,若innerHeight没变化,则软键盘未将页面顶起,会遮住底部输入框,此时添加样式类(比如通过样式留出软键盘空白,则不会遮挡输入框),来兼容这种情况
- 具体代码如下
const [needAndroidKeyboardSpace, setNeedAndroidKeyboardSpace] = useState(false); // 是否需要让出安卓键盘位置(bugFix: 安卓键盘弹出时遮挡输入框bug)
// ...
useEffect(() => {
// 保存下一进入的的初始页面高度
initialWindowHeight.current = window.innerHeight;
// focus时,通过innerHeight变化检测键盘是否弹出,决定是否需要让出键盘位置,防止遮挡用户输入
const checkAndroidKeyboard = (e) => {
// 需要模拟键盘弹出延迟,否则键盘还没弹出会提前获取innerHeight,则height不会变化
setTimeout(() => {
if (isAndroid() && e.type === 'focus' && initialWindowHeight.current === window.innerHeight) {
setNeedAndroidKeyboardSpace(true);
} else if (e.type === 'blur' && document?.activeElement?.tagName === 'BODY') {
// 检测页面失去焦点时(而非input失去焦点)恢复样式
setNeedAndroidKeyboardSpace(false);
// 兼容ios12 软键盘弹出后滚动页面后再收起键盘,页面没有复原导致底部留白&不能滑动 参考https://www.bbsmax.com/A/x9J2exQNz6/
if (isiOS() && getIOSVersion().startsWith('12')) {
window.scrollTo(0, 0);
}
}
}, 300)
}
window.addEventListener('focus', checkAndroidKeyboard);
window.addEventListener('blur', checkAndroidKeyboard);
return () => {
window.removeEventListener('focus', checkAndroidKeyboard);
window.removeEventListener('blur', checkAndroidKeyboard);
}
}, [])
1-2.ios12中iframe无法滚动问题
- 问题现象:在ios12系统中iframe中内嵌长页面但无法上下滑动
- 解决方法:
- 参考IFrame not scrolling on IOS Safari
- 给iframe增加父div,并增加兼容样式,即可滚动
// css
.iframeWrap {
width: 100%;
height: 100%;
-webkit-overflow-scrolling: touch;
overflow-y: scroll;
}
// jsx
<div className={s.iframeWrap}>
<iframe frameBorder={0} src={xxx} />
</div>
2.跨端框架相关
2-1.Taro使用navigateTo跳转,多个页面间样式互相影响
- 问题现象:Taro中webview使用
Taro.navigateTo跳转到其他页面,跳转路由过的多个页面中有相同元素(比如两个页面都有input)或者样式名(比如两个页面都有元素的样式名为s.input),则元素样式会互相影响 - 问题原因:
- taro的navigatoTo能实现页面的“丝滑”切换动画效果,是因为在路由时并未卸载组件,而是将用
Taro.navigateTo访问过的页面都压栈“暂存”起来,并展示最新访问的页面,跳回上一级路由时,会移除最新的页面dom;那么页面间的元素样式可能相互影响 - 比如A页面navigateTo B页面,再navigateToC页面,则dom结构如下:
-
- taro的navigatoTo能实现页面的“丝滑”切换动画效果,是因为在路由时并未卸载组件,而是将用
- 解决方法:
- 同名样式名进行样式名嵌套(我试了不管用,按道理应该有用的)
- 对样式更具体化,有一个bug是B页面的input样式不够具体,导致被第一个A页面的样式覆盖,则将B页面的被覆盖样式添加具体值使其不被覆盖即可