手机键盘自动收起,手机键盘弹出来怎么办
前言:前端时间也根据项目需要开始了h5移动端的折腾之旅。在现有中国移动终端的基础上扩建了两个ToC移动终端项目。下面是h5移动终端表单页面中键盘弹出和折叠兼容性的一些总结。
问题
在h5项目中,我们经常会遇到一些表单页面,当我们在输入框中获得焦点时会自动触发键盘弹出。但是IOS和Android的webview中键盘弹出的表现并不一致,我们主动触发键盘折叠起来也有差异。
键盘弹出
IOS:键盘IOS:IOS系统在窗口顶部。键盘弹出时,webview的高度不变,但scrollTop发生变化,可以滚动页面。并且页面可以滚动的最大范围是弹出的键盘的高度,当键盘弹出时页面刚好滚动到底部时,scrollTop的变化值就是键盘的高度,否则无法获得。这使得在IOS的情况下很难获得键盘的真实高度。Android:在Android系统中,键盘也在窗口的上方。键盘弹出时,如果输入框靠近底部,会被键盘挡住。只有输入时,输入框才会滚动到可视化区域。键盘收起
IOS:当键盘上的按钮被触发折叠键盘或输入框外的页面区域时,输入框会失去焦点,从而触发输入框的模糊事件;当键盘放好后,页面底部会出现一个空白区域,页面会被向上推。Android:当键盘上的按钮被触发折叠键盘时,输入框不会失去焦点,所以不会触发页面的模糊事件;当输入框外的区域被触发时,输入框会失去焦点,触发输入框的模糊事件。期望的结果
鉴于不同系统触发键盘弹出和折叠时的差异,我们希望在功能流畅的同时,尽可能保持用户体验的一致性。
对症下药
我们梳理了市面上两大系统的区别,接下来就需要对症下药了。
目前h5中还没有可以直接监听键盘事件的接口,但是我们可以通过分析键盘弹出和折叠的触发过程和表现形式来判断键盘是处于弹出还是折叠状态。
键盘弹出:当输入框获得焦点时,会自动触发键盘弹出。所以我们可以通过监控focusin事件来实现键盘弹出后所需的页面逻辑。折叠键盘:当其他页面区域被触发折叠键盘时,我们可以监听focusout事件来实现键盘折叠后所需的页面逻辑。但是当键盘被键盘键折叠起来的时候,ios和android是有区别的。下面详细分析一下:IOS:触发了focusout事件,仍然用这种方法监控。Android:focus out事件未被触发。在android中,键盘状态(弹出、折叠)的切换不仅与输入框有关,还会影响webview高度的变化,所以我们可以通过监测webview高度的变化来判断键盘是否折叠。系统判断
在实践中,我们可以通过userAgent来判断当前系统:
const ua=window . navigator . user agent . tolocalelowercase();const isIOS=/iphoneipadipod/。测试(ua);const isAndroid=/android/。测试(ua);IOS 处理
设isReset=true//是否返回handler=()={isreset=false中的this.focus//焦点时键盘弹出,焦点在输入框之间切换时,会先触发上一个输入框的失焦事件,再触发下一个输入框的焦点事件};this . focusouthandler=()={ is reset=true;SetTimeout(()={//当焦点在弹出层的输入框之间切换时,不要重置if (isReset) {window.scroll(0,0);//如果延迟后确定下一个元素没有聚焦,并且是折叠键盘导致的失焦,强制页面回到原处} },30);};document . body . addevent listener( focus in ,this . focus in handler);document . body . addevent listener( focus out ,this . focusouthandler);Android 处理
常量原点高度=文档。文档元素。客户高度 文档。身体。客户身高;这个。resize handler=()={ const resize height=document。文档元素。客户高度 文档。身体。客户身高;const活动元素=文档。活性元素;if(调整高度originHeight的大小){//键盘弹起后逻辑if(主动元素(主动元素。标记名=== INPUT 活动元素。tagname=== TEXTAREA ){ setTimeout(()={ active element。scrollintoview({ block: center });//焦点元素滚到可视区域的问题},0) } } else { //键盘收起后逻辑}};窗户。addevent侦听器( resize ,this。调整大小处理程序);react 封装
在反应中我们可以写一个类装饰器来修饰表单组件。
类装饰器:类装饰器在类声明之前被声明(紧靠着类声明)。类装饰器应用于类构造函数,可以用来监视,修改或替换类定义。
//keyboard.tsx/* * @描述:键盘处理装饰器* @作者:hzzly * @最后编辑:hzzly * @日期:2020-01-09 09:36:40 * @ LastEditTime:2020-01-10 12:08:47 */import React,{ Component } from React const keyboard=()=(wrapped Component:any)=class HOC扩展组件{处理程序中的焦点:(()=void)未定义;focusoutHandler:(()=void) undefined;resize处理程序:(()=void) undefined;componentdimount(){ const ua=window。领航员。用户代理。tolocalelowercase();const isIOS=/iphoneipadipod/.测试(ua);const isAndroid=/android/.测试(ua);if (isIOS) { //上面IOS处理.} if (isAndroid) { //上面机器人处理.} } componentWillUnmount(){ if(this。focusinhandler这个。focusouthandler){ document。身体。removeeventlistener( focusin ,this。focus in handler);文档。身体。removeeventlistener( focus out ,this。focusouthandler);}如果(这个。调整大小处理程序){ document。身体。移除事件侦听器( resize ,this。调整大小处理程序);} } render(){返回包装的组件{.这个。道具}/;} };导出默认键盘;使用
//PersonForm.tsx@keyboard()类人形扩展了PureComponent{},{} { //业务逻辑.}导出默认人员表单;以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。