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事件上过滤掉非字符键?