最近在做APP的时候,遇到了一个极其诡异的问题。App的做成触控屏和非触控屏通用的,触控屏操作就很简单,手指点击就触法,而非触控屏就需要遥控器支持了。原来一直是在触控屏上调试遥控器,看起来好像是没有问题,但是当切换到非触控屏调试时问题就来了,之前的一个小细节被忽略了。就是在触控屏上调试遥控器时,必须先点击一下屏幕空白处,再使用方向键控制才能生效。所以,非触控屏根本就没有办法用遥控器实现控制功能。
我们的遥控功能是利用document.activeElement结合focus事件来实现的,方向键切换,会使得页面的选中元素切换,再监听聚焦事件,判断当前元素支持选中,添加选中样式效果。根据当前表现情况来看,初步认为是activeElement元素的问题,点击一下空白处使得元素切换正常。只需要触发一下空白处的点击方法就行了。当然结果是没有任何效果。经过调试,初次进入页面activeElement元素就是body,点击一下空白处activeElement也是body。
后来,添加一个input输入框,在mounted中添加一行.focus()方法。windows模式下,输入框能够正常聚焦,而在app模式下,就是不能够聚焦。另外也尝试过input的autofocus属性,也是在app模式下无效。再次仔细研究,发现实际上activeElement元素已经选中input,只是没有光标,没有聚焦。
百度一下,你就知道。无计可施了,只能寻求万能的网友的帮助。但是在这茫茫大海找,要找到一个靠谱的答案还是要靠运气的。其中有一条引起了我的注意,这个场景与我们当前的符合度很高,同样都是引入了mui,并且无法自动获取焦点。
抱着试一试的态度,尝试了一番,结果还是有点失望,我们这个场景还是无法获取焦点,也有可能是写法问题。实际上,这个思路是正确的,确实是由于mui的影响,并且也是要通过nativeJs实现。
var nativeWebview, imm, InputMethodManager; var initNativeObjects = function() { if (mui.os.android) { var main = plus.android.runtimeMainActivity(); var Context = plus.android.importClass("android.content.Context"); InputMethodManager = plus.android.importClass("android.view.inputmethod.InputMethodManager"); imm = main.getSystemService(Context.INPUT_METHOD_SERVICE); } else { nativeWebview = plus.webview.currentWebview().nativeInstanceObject(); } }; var showSoftInput = function() { if (mui.os.android) { imm.toggleSoftInput(0, InputMethodManager.SHOW_FORCED); } else { nativeWebview.plusCallMethod({ "setKeyboardDisplayRequiresUserAction": false }); } setTimeout(function() { var inputElem = document.querySelector('input');//需要获得焦点的input inputElem.focus(); inputElem.parentNode.classList.add('mui-active'); //第一个是search,加上激活样式 }, 200); }; mui.plusReady(function() { initNativeObjects(); showSoftInput(); });
后来在其他地方找到类似的解决方案。
代码如下:
var autoFocusInput= function(id) { var nativeWebview, imm, InputMethodManager; //初始化NativeObject if(mui.os.android) { var main = plus.android.runtimeMainActivity(); var Context = plus.android.importClass("android.content.Context"); InputMethodManager = plus.android.importClass("android.view.inputmethod.InputMethodManager"); imm = main.getSystemService(Context.INPUT_METHOD_SERVICE); } else { nativeWebview = plus.webview.currentWebview().nativeInstanceObject(); } //获取焦点并调用软键盘 var nativeWebview = plus.webview.currentWebview().nativeInstanceObject(); if(mui.os.android) { //强制当前webview获得焦点 plus.android.importClass(nativeWebview); //这步很关键,不写的话获取焦点就无效 nativeWebview.requestFocus(); //imm.toggleSoftInput(0, InputMethodManager.SHOW_FORCED); } else { nativeWebview.plusCallMethod({ "setKeyboardDisplayRequiresUserAction": false }); } setTimeout(function() { var inputObj = document.getElementById(id); inputObj.focus(); //获取当前焦点所在的view并隐藏软件盘 var view = main.getCurrentFocus(); imm.hideSoftInputFromWindow(view.getWindowToken(),InputMethodManager.HIDE_NOT_ALWAYS); }, 200); } 调用:autoFocusInput("id");
与上面的区别,就在于多了var view = main.getCurrentFocus();这一行,获取焦点。
花了那么多时间,才解决这个问题,就记录一下吧。
还没有评论,来说两句吧...