

如上图所示:在移动端中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版权协议,转载请附上原文出处链接和本声明。