再也不想看到兼容问题了(持续更新)

777 阅读3分钟

背景

功能开发完进入二轮测试没什么bug了,前端内心正爽...

  • 测试:"有几个兼容问题,麻烦你看下"
  • 前端: "好的,机器都放这吧",内心一阵忧伤...

以此文记录自己遇到的兼容坑,避免再次踩坑 or 下次再见时能快速定位~

问题列表

1.移动端内webview相关

1-1.软键盘弹出遮挡input输入框问题

  • 问题现象:
    • 页面上有多个input框且靠近页面底部位置,当用户使用input输入时会吊起系统自带的软键盘,此时会有两种情况
      • case 1: 大部分ios & android中,软键盘自动顶起页面的输入框,用户输入不被遮挡
      • case 2: 少部分安卓机型,软键盘直接遮盖页面底部,用户输入被遮挡
  • 解决方法:
    • 在安卓端内,则监听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中内嵌长页面但无法上下滑动
  • 解决方法:
// 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结构如下:
  • 解决方法:
    • 同名样式名进行样式名嵌套(我试了不管用,按道理应该有用的)
    • 对样式更具体化,有一个bug是B页面的input样式不够具体,导致被第一个A页面的样式覆盖,则将B页面的被覆盖样式添加具体值使其不被覆盖即可