安卓+ios的输入框弹出键盘时,导致fixed或absolute定位的按钮顶上去的问题

如上图所示:在移动端中input唤起键盘的时候,会导致底部被fixed或者absoluted的button被顶上去,解决的第一思路就是要监听到键盘弹起的事件,对此解决方案要分为ios和android两种情况
以react为例,废话不说,直接上代码
视图层 :xxx.tsx

  // 利用窗口尺寸变化监听android键盘唤起和消失,利用聚焦失焦监听ios键盘唤起和消失
  const [resizeChange, setResizeChange] = useState(0)
  const [focus, setFocus] = useState(false)
  const originalHeight = document.body.clientHeight;

  // 分别解决android,ios弹起键盘时,按钮遮挡问题
  window.onresize = () => {
    const resizeHeight = document.body.clientHeight;
    onHideBtn(resizeHeight - originalHeight, focus)
    setResizeChange(resizeHeight - originalHeight)
  }
return(
.....
<div className={classNames(style.getMemberCardBox)}
      onFocus={() => {
        setFocus(true)
        onHideBtn(resizeChange, true)
      }}
      onBlur={() => {
        setFocus(false)
        onHideBtn(0, false)
        setResizeChange(0)
      }}>
      <div>输入框组件</div>
</div>
...
)

行为层:xxx.ts

  @observable hideBtn = false;
  @action onHideBtn = (resizeChange: number, focus: boolean) => {
    if (!focus) {
      // 当input失焦时,不考虑窗口大小变化
      this.hideBtn = false
    }
    if (focus && resizeChange > 0) {
      // 当input聚焦时,如果输入框关闭
      this.hideBtn = false
    }
    if (focus && resizeChange < 0) {
      // 当input聚焦时,如果输入框打开
      this.hideBtn = true
    }
    if (focus && resizeChange === 0) {
      // 当input聚焦时,如果窗口大小为默认状态
      this.hideBtn = true
    }
  }

hideBtn 即为控制按钮显示与否的状态

接下来对代码进行解释:

主要的原理是分别考虑focus事件和onresize 事件,在focus为true时,再去考虑onresize 导致的窗口高度是否发生变化

这是因为对于android,输入框的弹起必然导致onresize 事件的发生,窗口高度是一定会变化的,但焦点并不一定和此完全相关,例如,输入框获取焦点后,收回键盘,焦点并不会随之撤出;

android:

但ios上焦点和键盘弹出是绝对相关的关系,相反的,ios中键盘的弹起并不会触发onresize事件。

值得注意的地方是focus、blur事件和onresize 事件是三个独立的函数控制的,三个函数将状态传递给行为层进行综合处理,推断出hideBtn 状态。
在onresize 事件被触发时,也要同步改变窗口高度“setResizeChange(resizeHeight - originalHeight)”,在blur事件被触发时,最好也要清空窗口高度的变化“setResizeChange(0)”,否则三个函数内部的值无法做到同步。

当然还有一种更简便的逻辑处理方式,就是通过浏览器的User-Agent字段带回的设备类型信息,这个可以在window.navigator.userAgent中读取到,这样判断安卓和ios会更加明确一些,但实际上键盘的处理逻辑过程并没有什么简化的地方,还是一样的


版权声明:本文为weixin_42280395原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。