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

移动端输入法开发问题

时间:2023-04-02 21:58:22 HTML

作为前端开发,在工作中难免接触到input,根据input做一些定制化开发,但是由于Android和iOS系统的差异,宿主app的webview的选择(尤其是iOS),app的历史遗留问题等等,都会存在很多兼容性问题。下面,我将自己在开发过程中遇到的问题和解决方法记录下来。我希望它可以帮助你。1.ioswebview类型ios下不同app内置的webview可能不同,导致输入行为不一致。那么我们先来个大概的了解。目前ios系统下的webview有两种:WK和UI。ios8之前都是用UI的,自ios8以后,增加了WK类型。与UI相比,WK加载速度更快,更耗内存。更少,支持更多的h5特性,所以各大公司基本都会升级这个,但是不排除有一些app由于各种历史原因还在使用UI,比如我们的,目前我们的h5页面运行在多个app里面,有是UI和WK。自然是在开发的时候做一些兼容性判断来判断webview的类型//我还没有找到判断webview类型的好方法,除非ios开发告诉你//下面的方法只支持wkh5的新特性判断functiongetIosWebviewType(){if(navigator.platform.substr(0,2)==='iP'){//iOS(iPhone,iPodoriPad)constlte9=/constructor/i.test(window.HTMLElement);constnav=window.navigator;constua=nav.userAgent;constidb=!!window.indexedDB;if(ua.indexOf('Safari')!==-1&&ua.indexOf('Version')!==-1&&!nav.standalone){return'Safari'}elseif((!idb&<e9)||!window.statusbar.visible){重新turn'UI'}elseif((window.webkit&&window.webkit.messageHandlers)||!lte9||idb){return'WK'}}return'unknown'}2.自动对焦是否为h5规范无效或者caniuse勾选上面,这个属性是支持的,但是你在真机上测试的时候,很多时候并不是你想要的效果。目前我的测试情况如下:iosUIWebview可以聚焦,有光标,可以调出键盘WKWebview,可以聚焦,有光标,但是不能调出键盘Android暂时没发现问题(但不绝对)。我从网上了解到的原因是苹果希望由用户触发,输入操作是用户自愿的,而不是强制的,所以新版系统禁止了这个属性。旧版本的UI没有这个限制。好在Android和ios都支持同步<在touch或click事件中/u>执行input.focus()来聚焦并调出键盘。如果业务场景遇到这种情况,可以这样操作。onClick=()=>{this.input.focus()}但如果点击事件中有异步操作时,同autofocus属性一样,只能获得焦点,无法调用键盘onClick=()=>{setTimeout(()=>{this.input.focus()},1000)//或fetch('/api/get').then(()=>{this.input.focus()})}降级处理如果业务场景不满足上述情况,但是又需要这个功能,有解决方法focus之后,加强focus效果(因为原生光标显示毕竟不明显)设置一个focus样式,无论是在input上还是页面上的其他元素上,根据自己的产品特性和UE来确定合适的滚动页面,使它在视图中间,请参考3.聚焦问题3.1点击对焦后无法对焦或失焦。大部分情况是移动端的300ms问题导致的。一种是:app使用了UIWebview但是h5页面没有引入fastclick另一种是:引入了fastclick,但是需要优化一下fastclick的焦点,改成FastClick.prototype.focus=function(targetElement){targetElement.focus();};3.2光标无法聚焦到点击位置的概率很大也是fastclick造成的。请参考:link3.3已经如果有focusedinput,点击其他input,跳转的概率高也是fastclick造成的。可以参考上面的链接,也可以这样修改fastclick的源码,在onTouchEnd中增加一个新的判断。是否需要遵循原生的焦点逻辑FastClick.prototype.onTouchEnd=function(event){//...if(targetTagName==='label'){//...}elseif(this.needsFocus(targetElement)){//addif(!this.needsFocusInput())returnfalse//...}//...};//Added//如果已经有焦点元素,则直接进入原生输入焦点逻辑FastClick.prototype.needsFocusInput=function(){constfocusInput=document.querySelector('input:focus')return!focusInput}3.4提示以上问题大部分是fastclick引起的,但是fastclick(300ms)解决的问题目前大部分浏览器都解决了,所以确认一下。如果你的应用没有使用UIWebview,你可以直接去掉fastclick。fastclickgithub描述:注意:截至2015年底,大多数移动浏览器-特别是Chrome和Safari-不再有300毫秒的触摸延迟,因此fastclick对较新的bro没有任何好处wsers,并冒着将错误引入您的应用程序的风险。仔细考虑你是否真的需要使用它。4.失焦问题4.1希望保持焦点解决方法是让输入失焦:在点击事件中,阻止默认行为functiononClick(e){//你的事件处理代码...e.preventDefault();//部分iPhone机型不阻止默认行为是主动再次聚焦input.focus();}4.2我想主动失去焦点部分Android机型存在以下问题。在获得焦点的情况下,在不主动失去焦点的情况下点击页面其他地方。在某些情况下,主动隐藏键盘后,input并没有脱离焦点,而是当用户触摸到页面其他地方时,由于input还处于聚焦状态,键盘会被调出。有两种针对性的解决方案。第一种:监控用户行为,主动失去焦点constautoBlur=(e)=>{consttarget=e.targetconst{tagName,className}=target//点击非输入区域if(tagName.toUpperCase()!=='INPUT'){this.input.blur()}}文档。body.addEventListener('touchstart',autoBlur)第二种:监听键盘高度变化,主动失去焦点constonKeyboardChange=(resize)=>{//有时候,比如数字变成文字,或者系统自动在键盘上添加一些Decoration,键盘没有隐藏,但是会触发resize//在大多数机型上测试过,所有键盘的高度必须大于120,所以加一个limitif(Math.abs(resize)<120)returnconstshow=resize>0if(!show){this.input.blur()}}functiongetClientHeight()函数{返回document.documentElement.clientHeight||document.body.clientHeight;}//记录原始高度letoriginHeight=getClientHeight()//监听键盘变化window.addEventListener('resize',()=>{constresizeHeight=getClientHeight()constresize=originHeight-resizeHeightonKeyboardChange(调整大小);originHeight=resizeHeight;},false)5.聚焦后,滚动到视图中在大多数情况下,系统会帮助您将输入滚动到视图中。在少数情况下,我们需要自己设置一种方法是直接调用scrollIntoViewIfNeededapi,另一种是计算聚焦前后文档的高度差,然后相应地增加body的高度,以及设置滚动条。UIWebview下应该会出现这种情况//正常处理input.addEventListener('focus',()=>{setTimeout(()=>{this.input.scrollIntoViewIfNeeded();},300)})//UIWebview下的处理函数getClientHeight(){returndocument.documentElement.clientHeight||document.body.clientHeight;}constbodyHeight=getClientHeight()constbodyOverflow=getComputedStyle(document.body).overflowinput.addEventListener('focus',()=>{document.body.style.overflow='auto'setTimeout(()=>{//alert(getClientHeight())letheight=bodyHeight-getClientHeight()if(height<0)height=height*-2document.body.style.height=`${bodyHeight+height}px`;document.body.scrollTop=height;},300)})//如果设置了高度,在模糊时再设置回去input.addEventListener('blur',()=>{document.body.style.height=`${bodyHeight}px`;document.body.style.overflow=bodyOverflow})添加setTimeout因为键盘被唤醒时会有动画,我们需要在动画结束后滚动页面,否则计算出的高度不准确大多数情况下,键盘动画时间为小于3006强制光标到末尾target.focus()})7.其他一些问题7.1Cursorhidden在某些场景下,需要自定义输入框,自定义cursor等,Android可以通过opacity:0;隐藏原生cursor。color:transparent等但是ios无法隐藏,只能将input框移出view,先设置input宽度足够大,然后向左移动:input{width:1000px;margin-left:-200px;}7.2复制粘贴Android和ios都支持长按复制粘贴,但ios的前提是,光标必须在视图中。如上将输入向左移动后,粘贴按钮不在视图中,系统键盘上显示7.3短信验证码(或其他数字)。新版ios(应该是12+,不确定)系统收到以后会直接在键盘上显示文字信息,用户可以一键输入到input,但是老版不行不支持。用户需要主动复制短信,然后粘贴到输入框。如果输入是自定义的,则需要注意以上问题。部分安卓机(如小米6+)收到短信,可以直接点击通知栏复制,同样会出现在键盘上。8.结论以上基本上就是我在开发过程中遇到的问题。随着系统的迭代升级,很多问题都会被官方解决,但我们无法决定是否升级应用。决定用户是否应该升级。所以,如果你也遇到这些问题,希望能给你启发和帮助