Android 数字键盘上的输入事件监听器(onkeypress、onkeydown)无法正常工作

8
我不知道为什么,但在花费数小时处理后,我可以说有些地方出了问题。
我有一个简单的输入。
<input type="number">

我希望它只接受数字(数字[0-9]),不接受其他任何字符。为了实现这一点,我添加了一个事件侦听器,其中我控制事件的键码。
几乎所有平台上都没有问题,但在Android上出现了问题。在这里,type="number"会导致数字键盘出现 - 这很好 - 但也会出现一些其他字符(逗号、点、连字符...)。当您按下其中一个特殊字符时,行为是奇怪的:
- onkeypress事件:绝对不会触发(为什么?) - onkeydown事件:事件被触发并调用相关函数。问题在于浏览器已经键入了该字符(为什么?),因此无法调用“event”的“preventDefault”函数。 - oninput事件:事件正在触发,但“event”对象的“code”和“which”属性未定义。而且,就像以前一样,浏览器已经键入了该字符。
我错过了什么?
我的环境由AngularJs提供支持,因此我在指令中设置了事件侦听器。但是使用jQuery做同样的事情并不能解决问题。

有人建议使用"$parsers"来推送我的自定义值,而不带有不需要的字符。无论如何,我想这不起作用,因为输入的类型是"number",它只期望数字(另一种说法是Android浏览器正在做某些错误的事情..)

这里有一个可工作的Fiddle示例, 在Android上打开它。

3个回答

7

keypress 事件不会被触发,只有 keydownkeyup。在 onkeydown 中可以调用 preventDefault() 方法。但是要防止什么?charCode 总是为 0,而 keyCode229。您应该检查所有输入。

类似这样:

if(!event.charCode) {
    this.removeInvalidChar();
    return;
}

private removeInvalidChar(): void {
    setTimeout(() => {
        let input = this.control.control.value;

        if (input) {
            input.split('').forEach((char: string) => {
                if (!this.pattern.test(char)) {
                    input = input.replace(char, '');
                }
            });
            this.control.control.setValue(input);
        }
    });
}

"keypress事件没有被触发",这实际上是真正的问题!为什么没有被触发?这不正常。此外,您的代码将无法工作,因为在keydown事件中,字符已经在输入字段中(您可以删除它,但会产生丑陋的效果)。请在Android上尝试使用Fiddle。 - Ernesto Schiavo
好的,我使用 onkeyup...是的,结果并不理想...当无效的输入被替换时您会看到闪烁。 - Zoryana

2
这个指令使用$parsers.unshift实现,具体如何操作?
app.directive('format', ['$filter', '$window', function($filter, $window) {
  return {
    require: '?ngModel',
    link: function(scope, elem, attrs, ctrl) {

      if (!ctrl) return;

      scope.plainNumber = scope.test+'';

      ctrl.$parsers.unshift(function(viewValue) {         

      if(!viewValue){
         viewValue = scope.plainNumber;
      }
        scope.plainNumber = viewValue.replace(/[^\d]/g, '');

        elem.val(scope.plainNumber);
        return scope.plainNumber;            
      });
    }
  };
}]); 

使用方法:

<input type="number" ng-model="test" format /> 

演示Fiddle


在Android上测试过


这不是完美的,但我认为这是最好的选择,谢谢你。 - Ernesto Schiavo

1

使用inputType="numberSigned",它将为您提供0-9之间的数字,至少在原生Android中它可以完美工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接