页面底部输入框聚焦时吸底软键盘方案

0、参考布局

e219412c66890e80bbb9d2d49a23d603
e219412c66890e80bbb9d2d49a23d603 /

可能存在的问题

  • 输入框未跟随软键盘弹起
  • 输入框被顶起超过软键盘的高度
  • 输入框被系统手势按钮遮挡
  • 输入框没有被键盘挡住,但收起键盘后页面不会回落
  • ios safari标签栏位于底部时 100vh并不是真实的高度,导致输入框被标签栏遮挡
  • 输入框被顶起时,页面顶部被顶到了可视区域外
IMG_9606
IMG_9606 /


IMG_9607
IMG_9607 /


IMG_9605
IMG_9605 /


IMG_9604
IMG_9604 /

解决方案

1、Android

监听resize事件

在Android中,软键盘弹起会导致页面高度变化,压缩页面,因此可以通过监听windowresize事件,并实时修改容器高度来保证输入框位于软键盘之上

window.addEventListener('resize', this.convertStyle);

convertStyle() {
    this.$refs.container.style.setProperty('window.innerHeight', `${height}px`);
},

2、IOS

通过VisualViewport监听resize事件

在IOS中,软键盘的弹起并不会导致页面高度变化,而是会向底部添加一部分高度,使整个页面被顶起,并使底部fixed失效

IOS 13以后,新增了VisualViewport API 可以获取软键盘的高度
兼容性如图


VisualViewport MDN

通过监听VisualViewportresize事件,并使用visualViewportheight实时修改容器高度来保证输入框位于软键盘之上

需要注意的是 safari当导航栏处于底部时,resize事件的触发会很迟钝,导致输入框弹起稍慢,safari当导航栏处于顶部时无此问题,该问题在 ios16 Beta 中仍未修复

window.visualViewport.addEventListener('resize', this.convertStyle);

convertStyle() {
    this.$refs.container.style.setProperty('window.visualViewport.height', `${height}px`);
},

3、安全区

iphoneX以后因为全面屏底部触控条及刘海的存在,苹果牵头增加了env() safe-area-inset-XXX 属性 可以获取到安全区的高度

仅支持 ios 11.2 以上,安卓阵营部分浏览器最新版依然不支持该属性

padding-bottom: constant(safe-area-inset-bottom); /* 兼容 iOS < 11.2 */
padding-bottom: env(safe-area-inset-bottom); /* 兼容 iOS >= 11.2 */

还需要注意的是使用该属性 需要提前设置meta标签

<meta name="viewport" content="width=device-width, viewport-fit=cover">

4、safair 聚焦 弹起高度过高的问题

在使用VisualViewport相关API重设容器高度的过程中,可能概率性出现页面被浏览器整体弹高的问题,在resize事件中,强制滚动到顶部,可以解决该问题 需要注意的是滚动建议在resize事件的10ms(测试出的兼容值)中执行,不然可能导致抖动、不生效等问题

window.visualViewport.addEventListener('resize', this.convertStyle);

convertStyle() {
    this.$refs.container.style.setProperty('window.visualViewport.height', `${height}px`);
    setTimeout(() => {
        window.scrollTo(0, 1);
    }, 10);
},

遗留问题

  • 部分安卓浏览器没有设置安全区
  • safari当导航栏处于底部时,输入框弹起卡顿

Subscribe to ionantha

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
jamie@example.com
Subscribe