keypress和keydown优先于Firefox和Safari中的粘贴事件

我有一个使用jqlite的Angular指令,我想绑定一个keypress,keydown和paste事件来更新指令的选项。

我使用以下命令绑定到paste,keypress和keydown事件:

input.bind("paste.elementClass", updateOptions); input.bind("keypress.elementClass", updateOptions); // keypress does not fire if the backspace/delete button is pressed. This keydown listener triggers the // keypress event if backspace/delete is pressed. Didn't use keydown listener instead of keypress because // keydown did not register if multiple buttons are pressed (shift + d). The keyup event choked // if a button was pressed and held for longer than the model debounce time. input.bind("keydown.elementClass", function() { // handle this event differently }); 

 function updateOptions(event) { var key = event.which || event.keyCode; if (event.type === 'paste') { scope.internalModel.searchText = event.originalEvent.clipboardData.getData('text'); } else { scope.internalModel.searchText = key ? String.fromCharCode(key) : ""; } scope.onModelChange(scope.internalModel); } 

我测试了我的代码,这个解决方案在Chrome中运行良好。 但是,当我在Firefox和Safari中测试时,它失败了。 看来,当我尝试从剪贴板粘贴时,只会调用附加到keypress事件的函数。 如果我注释掉我对keypress的绑定,那么附加到keydown的函数将被调用。 最后,如果我注释掉keypress和keydown,那么绑定到paste的函数将被调用并正常工作。

有没有办法防止keydown和keypress事件在从剪贴板粘贴并仍然分别检测到keydown和keypress时在Firefox和safari上被触发/调用?


更新

仍然没有运气找到这个问题的答案我尝试使用ng-paste,ng-keypress和ng-keydown。 我已经尝试过paste.addEventListener用于paste,keypress和keydown。 我没有运气就使用过jQuery的.on和.bind。

我创造了一个再现问题的plunkr。


最后更新

我找到了一个如下所示的解决方案而不是使用keypress我使用keyup和keydown事件来检测何时按下了control或meta(超级/窗口)键。 然后我过滤掉必要的关键事件。 我的最终解决方案是使用jQuery绑定和取消绑定事件。

请参阅最终解决方案http://plnkr.co/edit/EI0otzqCZrYWCA8GgeNY?p=preview

好的,我想我找到了一些关于这个问题的信息。 与keydown事件相比,只有在按下显示字符的键时才会触发keypress :字母,数字等(可打印键)。 但问题是没有关键keypress事件的官方规范,因此浏览器以不同的方式实现它。 例如,在Chrome中cmd + v命令不会触发keypress事件,但在Firefox和Safari中它会(就像你只按v键一样)并且它会以某种方式破坏paste命令,因此它不会触发。

如果您尝试通过上下文菜单将文本粘贴到输入中,您会发现它工作正常。

所以我想如果你想要监听paste事件,建议使用keydown / keyup事件而不是keypress


一些相关问题:

  • onKeyPress与 onKeyUp和onKeyDown
  • jQuery:如何在keypress事件上过滤掉非字符键?