输入事件侦听器(onkeypress、onkeydown)在 Android 数字键盘中不起作用

Posted

技术标签:

【中文标题】输入事件侦听器(onkeypress、onkeydown)在 Android 数字键盘中不起作用【英文标题】:Event listeners (onkeypress, onkeydown) on input not working in Android numeric keyboard 【发布时间】:2017-06-24 20:46:33 【问题描述】:

我不知道为什么,但经过几个小时的处理,我可以说有问题。

我有一个简单的输入

<input type="number">

我希望它只接受 数字(数字 [0-9]),仅此而已。为了实现这一点,我添加了一个事件监听器,用于控制事件的键码。

没有什么特别的,几乎所有平台都可以运行,android 会出现问题。这里的

type="数字"

使数字键盘出现 - 这很棒 - 还有一些其他字符(逗号、点、连字符......)。当您按下其中一个特殊字符时,行为很奇怪:

onkeypress 事件:绝对不触发(为什么???) onkeydown 事件:事件被触发并调用相关函数。问题是浏览器已经输入了字符(为什么??)所以无法调用“event”的“preventDefault”函数。 关于输入事件:事件正在触发,但“事件”对象的“代码”和“哪个”属性未定义。此外,和以前一样,浏览器已经输入了字符

我错过了什么?

我的环境由 AngularJs 提供支持,因此我在指令中设置了事件侦听器。然而,用 jQuery 做同样的事情并不能解决问题。

有人可以建议使用“$parsers”来推送我的自定义值而不需要不需要的字符。无论如何,我猜这不起作用,因为输入的类型是“数字”并且它只需要数字(另一种说法是Android上的浏览器做错了什么......)

这里有一个working Fiddle,在Android上打开它。

【问题讨论】:

【参考方案1】:

keypress 事件不会被触发,只有keydownkeyuponkeydown 你可以调用 preventDefault() 方法。但是要预防什么呢? charCode 始终是 0keyCode229。您应该检查所有输入。

类似这样的:

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);
        
    );

【讨论】:

“按键事件没有被触发”,实际上这是真正的问题!为什么不被解雇?这不正常.. 此外,您的代码将不起作用,因为在 keydown 事件中 char 已经在输入字段内(您可以将其删除,但会产生丑陋的效果)。请在 Android 上使用 Fiddle 试试 好吧,我在keyup上使用它...是的,结果并不理想...当无效输入被替换时,您会看到闪烁。【参考方案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 /> 

Demo Fiddle


在 Android 上测试

【讨论】:

这并不完美,但我认为这是最好的选择,谢谢【参考方案3】:

使用 inputType="numberSigned" 它只会为您提供 0-9 之间的数字,至少在原生 android 中它可以完美运行。

【讨论】:

以上是关于输入事件侦听器(onkeypress、onkeydown)在 Android 数字键盘中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

OnKeyPress、onKeyDown、onKeyUp 事件在 Android 下的 Firefox/Chrome 中在键入字母时未触发

js中onkeyuponkeydown和onkeypress的区别

仅允许onKeyPress或onKeyDown中的React中的数字

text输入框改变事件

监听input变化的事件

如何处理 ReactJS 中的 `onKeyPress` 事件?