处理ios软键盘弹起和收起时页面滚动问题
背景:
在开发添加主播功能时,页面底部需要弹出一个抽屉弹窗,点击抽屉上的输入框,会唤起软键盘,由于iOS的软键盘触发方式是将页面滚动,所以导致页面位置偏移
bug描述:
<必现>iOS:添加主播成功后 页面会定位在节目设置页的最底部
解决过程:
经过google看了一大堆资料,找到了核心原因,就是ios的滚动scroll
效应。
网络上有大量的解决方案是获取当前页面的滚动高度(scrolltop
),然后在页面outfocus
时,使用window.scroll把页面滚动回去。
但是这个方法会存在很多问题
- 由于本身该页面就存在一个底部抽屉组件,scroll回去的时候页面滚动效果非常明显,页面就像重新渲染了一次,抽屉会重新弹起,体验非常差。
-
outfocus
不太稳定,页面上有select
和其他输入的时候,弹起选择框,也会触发onfocus
,整个页面就乱滚
核心问题其实是底下的主内容在乱动,所以把它固定住不要让他滚动就好了,所以最后还是选择在底部弹窗出现的时候把整个页面fixed固定住,阻止整个内容滚动。
- 获取弹窗出现是页面的
scrolltop
- 弹窗出现时设置style:
position:fixed; top:-scrollTop;
- 弹窗消失时,恢复原本的页面定位,并用
window.scroll(0, scrollTop)
恢复到原先页面的位置。
iOS
和Android
软键盘弹起/收起的不同形式:
在 IOS
上,
输入框(input
、textarea
或 富文本)获取焦点,软键盘弹起,页面(webview
)并没有被压缩,或者说高度(height
)没有改变,只是页面(webview
)整体往上滚了,且最大滚动高度(scrollTop
)为软键盘高度。
触发软键盘上的“收起/完成”按钮键盘或者输入框以外的页面区域时,输入框失去焦点,软键盘收起。注意:页面依然是键盘弹起时scroll到的位置。
在 Android
上,
输入框获取焦点,键盘弹起,但是页面(webview
)高度会发生改变,一般来说,高度为可视区高度(原高度减去软键盘高度),除了因为页面内容被撑开可以产生滚动,webview
本身不能滚动。
触发输入框以外的区域时,输入框失去焦点,软键盘收起。但是,触发键盘上的收起按钮键盘时,输入框并不会失去焦点,同样软键盘收起。页面恢复正常。