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

1. 键盘弹出的不同表现IOS:IOS 的键盘处在窗口的最上层,当键盘弹起时,webview 的高度 height 并没有改变,只是 scrollTop 发生变化,页面可以滚动。且页面可以滚动的最大限度为弹出的键盘的高度,而只有键盘弹出时页面恰好也滚动到最底部时,scrollTop 的变化值为键盘的高度,其他情况下则无法获取。这就导致在 IOS 情况下难以获取键盘的真实高度。

Android: webview 中留出空间,该空间小于等于的键盘空间,变化的高度差会随着布局而不同,有的认为 键盘高度 + 页面高度 = 原页面高度; 是错误的误导,只有在某种很巧合的布局情况下才可套用此公式。

2. 键盘收起的不同表现IOS:触发键盘上的按钮收起键盘或者输入框以外的页面区域时,输入框会失去焦点,因此会触发输入框的 blur 事件。

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

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

在 h5 中目前没有接口可以直接监听键盘事件,但我们可以通过分析键盘弹出、收起的触发过程及表现形式,来判断键盘是弹出还是收起的状态。键盘弹出:输入框获取焦点时会自动触发键盘的弹起动作,因此,我们可以监听输入框的 focus 事件,在里面实现键盘弹出后所需的页面逻辑。这在 ios 及 android 中表现一致。

键盘收起:从第 2 部分可知,触发键盘收起的不同形式会存在差异化表现,当触发其他页面区域收起键盘时,我们可以监听输入框的 blur 事件,在里面实现键盘收起后所需的页面逻辑。而在通过键盘按钮收起键盘时在 ios 与 android 端存在差异化表现,下面具体分析:

IOS:触发了输入框 blur 事件,仍然通过该办法监听。

Android:没有触发输入框的 blur 事件。但通过第 1、2 部分我们可以知道,在 android 中,键盘的状态切换(弹出、收起)不仅和输入框关联,同时还会影响到 webview 高度的变化,那我们不妨通过监听 webview height 的变化来判断键盘是否收起。

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

Welcome to TXD!

ios & android 键盘弹出:

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

ios 键盘收起:

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

android 键盘弹出与收起:

/*键盘弹起后页面高度变小*/ 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. 使用案例

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

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

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

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

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

ios 的 height 没有发生变化,页面可以滚动;

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

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

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

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

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

5. 小结在 ios 中,无论何种布局,为了使输入框展示在可视区域中,键盘弹出时,页面会向上滚动,该过程与 Element.scrollIntoViewIfNeeded() 方法(将不在浏览器窗口的可见区域内的元素滚动到浏览器窗口的可见区域)产生的效果一致;且高度始终不变,页面可滚动。

在 android 中,键盘唤起后,页面可滚动与否由其处在正常文档流中的元素决定:如果正常文档流中的元素可全量展示,页面不可滚动,否则页面支持滚动;

在 android 中,键盘唤起后,fixed 元素的基准会发生变化:根据 bottom 定位的元素,其基线变为键盘上部;根据 top 定位的元素,仍然根据页面顶部,因此为照顾正常文档流及 fixed 元素的用户体验,有的元素可根据顶部定位,有的可以根据底部定位。

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

h5如何动态获取键盘高度_H5 键盘兼容性小结相关推荐

  1. iPhone和ipad键盘高度及键盘响应事件 摘

    iPhone和ipad键盘高度及键盘响应事件 http://blog.csdn.net/benbenxiongyuan/article/details/7892019 IPAD键盘高度: portra ...

  2. android 如何判断h5页面是否加载完成_H5 键盘兼容性小结

    " 我们经常需要填写表单,键盘的行为存在各种差异." 在 H5 项目中,我们会经常遇到页面中存在单个甚至多个 input/textarea 输入框与底部固定元素的布局情况.在 in ...

  3. h5底部输入框被键盘遮挡_H5 键盘兼容性小结

    " 我们经常需要填写表单,键盘的行为存在各种差异." 在 H5 项目中,我们会经常遇到页面中存在单个甚至多个 input/textarea 输入框与底部固定元素的布局情况.在 in ...

  4. android accessibility 模拟键盘事件_H5 键盘兼容性小结

    在 H5 项目中,我们会经常遇到页面中存在单个甚至多个 input/textarea 输入框与底部固定元素的布局情况.在 input/textarea 输入框获取焦点时,会自动触发键盘弹起,而键盘弹出 ...

  5. 『IOS』iPhone和ipad键盘高度及键盘响应事件

    原文地址:http://blog.csdn.net/benbenxiongyuan/article/details/7892019 IPAD键盘高度: portrait  264 landscape ...

  6. iPhone和ipad键盘高度及键盘响应事件

    IPAD键盘高度: portrait  264 landscape  352. iPhone键盘高度: Portrait  216 Landscape  140 背景: ios5之前,iphone上的 ...

  7. uniapp 动态获取元素高度

    vue页面获取元素, app端推荐(这个也兼容H5) //设置mescroll的高度setTimeout(()=>{const query = uni.createSelectorQuery() ...

  8. vue mixins(vue3 hooks)动态获取div高度

    之前转载过一篇文章: https://blog.csdn.net/qq_37167049/article/details/103084927 可以动态计算div 高度,但是比较繁琐的痛点是: 需要在每 ...

  9. h5如何动态获取键盘高度_动态获取键盘高度

    //在遇到有输入的情况下.由于现在键盘的高度是动态变化的.中文输入与英文输入时高度不同.所以输入框的位置也要做出相应的变化 #pragma mark - keyboardHight -(void)vi ...

最新文章

  1. 习题10-6 递归求Fabonacci数列 (10 分)
  2. sqlite3 多线程 c语言,sqlite3 c语言编程 之 三个基本函数
  3. python小练习--模拟用户登录,(3次重试机会,登录成功展示登录账号密码)
  4. Shell脚本基本命令4
  5. python转换函数使用_python进制转换函数代码的使用
  6. 10个管理工作时间的小技巧
  7. 智能物联网系统安全与防御【会议】
  8. 超松弛迭代法(C语言实现)
  9. 持有1000枚比特币及以上的地址数量创历史新高
  10. win10打印机不能服务的问题
  11. EMC trainning杂谈
  12. python pdf提取数据_python从PDF中提取数据的示例
  13. eis系统 java_Java消息系统介绍 - marvin_vov的个人空间 - OSCHINA - 中文开源技术交流社区...
  14. 2017年寒假集训分组测试赛2 Ranklist
  15. 【读书笔记】《数学之美》——一个好方法在形式上总是简单的
  16. 1202 -- 童年生活二三事
  17. u盘怎么安装计算机系统软件,教你怎样用u盘安装win7x64系统
  18. 吉林建筑大学电气与计算机学院讲师,吉林建筑大学导师教师信息介绍-电气与计算机学院刘航...
  19. CAD图纸无法正常缩放怎么办?如何解决?
  20. Java项目:医院电子病历管理系统(java+Servlet+JSP+Easyui+Mysql)

热门文章

  1. Linux命令解释之groupadd,groupdel,groupmod,groupmems
  2. matlab hopty,运行Matlab时出现错误?Attempted to access rxd(500); index out of bou
  3. C# 操作iis6、iis7 301
  4. 【转】Android 最火框架XUtils之注解机制详解
  5. ServletResponse的getOutputStream()与getWriter()使用冲突
  6. PostgreSQL主要优势
  7. 所有浏览器主页惨遭篡改:http://wangzhi6.dhtz444.top/或https://www.2345.com/
  8. mysql gtid 集群_Docker搭建MySQL主从集群,基于GTID
  9. 图解Golang的GC算法
  10. Unity对接Steam SDK