最近在做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();这一行,获取焦点。
花了那么多时间,才解决这个问题,就记录一下吧。
还没有评论,来说两句吧...