当前位置: 首页 > Web前端 > HTML5

可能这些是你想要的H5软键盘兼容方案

时间:2023-04-05 21:37:58 HTML5

或许这些就是你想要的输入法框上的H5软键盘兼容解决方案。需求很明确,看似很简单,其实不然。通过在部分机型上的实验,发现主要存在以下问题:在Android和IOS上,已知软键盘的弹出和折叠状态存在差异,页面webview表现不同。IOS12,微信版本v6.7.4及以上,输入框获取焦点,键盘弹出,页面(webview)整体向上滚动。键盘收起后,没有回到原来的位置,导致键盘原位空白。IOS上,使用第三方输入法,高度计算存在偏差,导致部分输入法弹出,部分遮挡输入框。在某些浏览器上使用一些操作技巧,输入框仍然被输入法挡住。下面我们就针对上述问题一一探讨解决方法。知道软键盘的上下状态知道软键盘是向上还是向下是非常重要的,下面的兼容处理必须基于此。但是H5并没有直接监听软键盘的原生事件,只能通过软键盘的弹出或者收回来间接监听,触发页面其他方面的表现,曲线救国。此外,它在IOS和Android上的工作方式也不尽相同。IOS软键盘弹出IOS上,输入框(input,textarea或富文本)获得焦点,弹出键盘,页面(webview)没有压缩,或者高度(height)没有变化,只是页面(webview)整体向上滚动,最大滚动高度(scrollTop)为软键盘高度。Android软键盘弹出的行为是一样的。在Android上,输入框获得焦点,弹出键盘,但是页面(webview)的高度会发生变化。一般来说,高度就是可见区域的高度(原始高度减去软键盘的高度),除了因为页面内容被拉伸会发生滚动外,webview本身是不能滚动的。IOS软键盘折叠表现当触发软键盘或输入框外页面区域的“折叠”按钮时,输入框失去焦点,软键盘折叠。Android软键盘折叠触发输入框外区域时,输入框失去焦点,软键盘折叠。但是当键盘上的retract按钮被触发时,输入框不会失去焦点,软键盘也会塌陷。监听软键盘的弹出和折叠根据上述键盘弹出和折叠在IOS和Android上的不同表现,我们可以分别进行如下处理来监听软键盘的弹出和折叠keyboard:在IOS上监听输入框focus事件用来知道软键盘弹出,监听输入框的blur事件知道软键盘关闭。在Android上,监控webview的高度会发生变化,高度变小就知道软键盘弹出,否则软键盘会缩回。//判断设备类型varjudgeDeviceType=function(){varua=window.navigator.userAgent.toLocaleLowerCase();varisIOS=/iphone|ipad|ipod/.test(ua);varisAndroid=/android/.test(ua);return{isIOS:isIOS,isAndroid:isAndroid}}()//监听输入框的软键盘弹出和关闭事件functionlistenKeybord($input){if(judgeDeviceType.isIOS){//IOS键盘弹出:IOS和Android输入框获得焦点弹出键盘$input.addEventListener('focus',function(){console.log('IOS键盘弹出!');//IOS键盘弹出后的操作},false)//IOS键盘收回:IOS点击输入框外区域或点击收回按钮,输入框失去焦点,键盘收回,$input.addEventListener('blur',()=>{console.log('IOS键盘收起!');//IOS键盘收起})}//Andriod键盘收起:Andriod键盘弹出或收起时页面高度会发生变化,基于键盘缩回if(judgeDeviceType.isAndroid){varoriginHeight=document.documentElement.clientHeight||文档.body.clientHeight;window.addEventListener('resize',function(){varresizeHeight=document.documentElement.clientHeight||document.body.clientHeight;if(originHeight请输入您的电话号码

type="tel”,是HTML5的一个属性,表示输入框类型是电话号码,在Android和IOS上表现类似。会有数字键盘,但也会有字母,略显多余。pattern="[0-9]",pattern用于验证表单的输入内容,通常是HTML5的type属性,如email、tel、number、dataclass、url等,已经有一个简单的数据格式验证功能。添加pattern后,前端部分的验证更加简单高效。在IOS中只有[0-9]\*可以激活九宫格数字键盘,\d无效,Android4.4及以下(包括X5内核)都可以激活数字键盘。novalidate="novalidate",novalidate属性规定表单提交时不验证。由于模式验证的兼容性不好,无法验证,只能让它唤起纯数字键盘,验证工作由js完成。兼容IOS12+V6.7.4+如果你用IOS12和V6.7.4+版本的微信浏览器打开上面表单输入的demo,你会惊奇地发现,键盘关闭后,原来的页面向上滚动不返回底部弹出键盘的位置是“空”。其实这是苹果IOS的一个bug,它会出现在所有用Xcode10打包的IOS12设备上。微信官方给出了解决方案,只要把软键盘收起后,将页面(webview)滚动回窗口底部位置(clientHeight位置)即可。上面修复的表单输入demo可以点这里console.log('IOS键盘关闭!');//IOS键盘关闭后的操作//微信浏览器版本6.7.4+IOS12会显示键盘关闭后,视图已上推但未下推varwechatInfo=window.navigator.userAgent.match(/MicroMessenger\/([\d\.]+)/i);if(!wechatInfo)return;varwechatVersion=wechatInfo[1];varversion=(navigator.appVersion).match(/OS(\d+)_(\d+)_?(\d+)?/);if(+wechatVersion.replace(/\./g,'')>=674&&+version[1]>=12){setTimeout(function(){window.scrollTo(0,Math.max(document.body.clientHeight,document.documentElement.clientHeight));})}兼容第三方输入法上面说了这么多,其实H5聊天输入框的坑已经填了一大半了。接下来我们看一下聊天输入框的基本HTML结构。

一些聊天内容1

styles/*省略部分样式*/.chat__content{height:calc(100%-40px);底部边距:40px;溢出-y:自动;溢出-x:隐藏;}.input__content{显示:flex;高度:40px;位置:绝对;左:0;右:0;底部:0;就是划分内容区和输入区。输入区域是绝对定位的。根据上面的表单输入demo方法,确实大部分安卓浏览器都没有问题,但是测试是在IOS上。UC浏览器配合原生输入法和第三方输入法。输入法(如搜狗输入法),输入框会被完全遮挡;QQ浏览器或微信浏览器,使用第三方输入法,输入框会被半遮住;带有第三方输入法输入框的百度浏览器也会被屏蔽全屏蔽的效果可以在对应的浏览器中访问这里。在UC浏览器上,弹出软键盘后,浏览器上方的标题栏高度有一个递减高度和延迟的动态效果,导致webview向下滚动一点,底部的输入框滚动到不可见区域。至于第三方输入法,自己猜测是由于输入法面板弹出后的高度计算错误导致webview初始滚动定位错误。其实这两点都是webview滚动不够充分造成的。软键盘弹出后,让focus元素再次滚动到可见区域,强制webview原地滚动。console.log('安卓键盘弹出!');//安卓键盘弹出后运行activeElementScrollIntoView($input,1000);Android小米浏览器兼容的hack解决方案在Android小米浏览器上,应用上述解决方案,发现聊天输入框依然被死死堵住,scrollIntoView()依然一动不动。所以猜测,其实就是滚动到底部,弹出软键盘,页面高度大于可见区域高度。这样只能在软键盘弹出后强行增加页面高度,才能显示输入框。基于以上对第三方输入法的兼容,可以点此查看效果//Andriod键盘收起:Andriod键盘弹出或收起时页面高度会发生变化,如果键盘收起则基于此(judgeDeviceType.isAndroid){varoriginHeight=document.documentElement.clientHeight||文档.body.clientHeight;window.addEventListener('resize',function(){varresizeHeight=document.documentElement.clientHeight||document.body.clientHeight;if(originHeight