H5 键盘兼容性小结

H5 键盘兼容性小结

在 H5 项目中,咱们会常常遇到页面中存在单个甚至多个 input/textarea 输入框与底部固定元素的布局状况。在 input/textarea 输入框获取焦点时,会自动触发键盘弹起,而键盘弹出在 ios 与 android 的 webview 中表现并不是一致,同时当咱们主动触发键盘收起时也一样存在差别化。而不管如何,咱们但愿功能流畅的同时,尽可能保持用户体验的一致性,所以有了下面一系列兼容性问题的研究。android

 

1. 键盘弹出的不一样表现

  • IOS:IOS 的键盘处在窗口的最上层,当键盘弹起时,webview 的高度 height 并无改变,只是 scrollTop 发生变化,页面能够滚动。且页面能够滚动的最大限度为弹出的键盘的高度,而只有键盘弹出时页面刚好也滚动到最底部时,scrollTop 的变化值为键盘的高度,其余状况下则没法获取。这就致使在 IOS 状况下难以获取键盘的真实高度。
  • Android: webview 中留出空间,该空间小于等于的键盘空间,变化的高度差会随着布局而不一样,有的认为 键盘高度 + 页面高度 = 原页面高度; 是错误的误导,只有在某种很巧合的布局状况下才可套用此公式。

2. 键盘收起的不一样表现

  • IOS:触发键盘上的按钮收起键盘或者输入框之外的页面区域时,输入框会失去焦点,所以会触发输入框的 blur 事件。
  • Android: 触发键盘上的按钮收起键盘时,输入框并不会失去焦点,所以不会触发页面的 blur 事件;触发输入框之外的区域时,输入框会失去焦点,触发输入框的 blur 事件。

3. 监听键盘的弹出与收起

在 h5 中目前没有接口能够直接监听键盘事件,但咱们能够经过分析键盘弹出、收起的触发过程及表现形式,来判断键盘是弹出仍是收起的状态。ios

  • 键盘弹出:输入框获取焦点时会自动触发键盘的弹起动做,所以,咱们能够监听输入框的 focus 事件,在里面实现键盘弹出后所需的页面逻辑。这在 ios 及 android 中表现一致。
  • 键盘收起:从第 2 部分可知,触发键盘收起的不一样形式会存在差别化表现,当触发其余页面区域收起键盘时,咱们能够监听输入框的 blur 事件,在里面实现键盘收起后所需的页面逻辑。而在经过键盘按钮收起键盘时在 ios 与 android 端存在差别化表现,下面具体分析:
    • IOS:触发了输入框 blur 事件,仍然经过该办法监听。
    • Android:没有触发输入框的 blur 事件。但经过第 一、2 部分咱们能够知道,在 android 中,键盘的状态切换(弹出、收起)不只和输入框关联,同时还会影响到 webview 高度的变化,那咱们不妨经过监听 webview height 的变化来判断键盘是否收起。

下面举例说明,其中页面中含有一个输入框:web

<div class="txd"> Welcome to TXD! </div> <div class="input"> <input id="input" type="tel" /> </div> 复制代码

ios & android 键盘弹出:浏览器

const $input = document.getElementById('input'); $input.addEventListener('focus', () => { // 处理键盘弹出后所需的页面逻辑 }, false); 复制代码

ios 键盘收起:bash

const $input = document.getElementById('input'); $input.addEventListener('blur', () => { // 处理键盘收起后所需的页面逻辑 }, false); 复制代码

android 键盘弹出与收起:iphone

/*键盘弹起后页面高度变小*/
const originHeight = document.documentElement.clientHeight || document.body.clientHeight;
window.addEventListener('resize', () => { const resizeHeight = document.documentElement.clientHeight || document.body.clientHeight; if (resizeHeight < originHeight) { // 键盘弹起所后所需的页面逻辑 } else { // 键盘弹起所后所需的页面逻辑 } }, false); 复制代码

在实践中经过判断 userAgent 来决定使用哪一种方法:布局

const ua = window.navigator.userAgent.toLocaleLowerCase();
const isIOS = /iphone|ipad|ipod/.test(ua);
const isAndroid = /android/.test(ua);
复制代码

4. 使用案例

接下来根据上面的讨论说明几种常见场景:post

(1)头部及中间输入框处于正常的文档流,底部元素 fixed优化

 

ios 键盘遮挡在页面上,页面高度始终不变,页面能够滚动,底部元素被遮挡;ui

android 页面高度减小,页面不可滚动,fixed 元素的 bottom 属性的基线为键盘;

(2)头部及输入框处于正常文档流,且所占可视区域变大,底部元素 fixed

 

ios 的 height 没有发生变化,页面能够滚动;

android 页面高度变小,但为了使正常文档流的元素能够正常显示,页面能够上下滚动,fixed 元素的 bottom 属性的基线为键盘;

(3)头部处于正常文档流,输入框脱离正常文档流 fixed bottom 定位


(上面为了便于观察,将输入框包裹元素的背景设置了透明度)

 

ios 的 height 没有发生变化,且始终保证输入框处于可视区域中;

android 页面高度变小,页面不可滚动,fixed 输入框 bottom 属性的基线为键盘;

5. 小结

  1. 在 ios 中,不管何种布局,为了使输入框展现在可视区域中,键盘弹出时,页面会向上滚动,该过程与 Element.scrollIntoViewIfNeeded() 方法(将不在浏览器窗口的可见区域内的元素滚动到浏览器窗口的可见区域)产生的效果一致;且高度始终不变,页面可滚动。
  2. 在 android 中,键盘唤起后,页面可滚动与否由其处在正常文档流中的元素决定:若是正常文档流中的元素可全量展现,页面不可滚动,不然页面支持滚动;
  3. 在 android 中,键盘唤起后,fixed 元素的基准会发生变化:根据 bottom 定位的元素,其基线变为键盘上部;根据 top 定位的元素,仍然根据页面顶部,所以为照顾正常文档流及 fixed 元素的用户体验,有的元素可根据顶部定位,有的能够根据底部定位。

在了解清楚 h5 中键盘的弹出收起的性质后,在处理兼容性问题会容易不少。同时也可以使用Element.scrollIntoViewIfNeeded() 方法辅助解决问题(好比在切换不一样的输入法时,可能致使有用信息被遮挡的状况)优化体验。

做者:阿里巴巴TXD连接:https://juejin.im/post/5c6d1c8b6fb9a049de6df441来源:掘金著做权归做者全部。商业转载请联系做者得到受权,非商业转载请注明出处。

相关文章
相关标签/搜索