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

Bri*_*usk 5 javascript jquery angularjs

我有一个使用 jqlite 的 Angular 指令,我想绑定一个按键、按键和粘贴事件来更新指令上的选项。

我使用以下方法绑定到 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
});
Run Code Online (Sandbox Code Playgroud)

...

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);
}
Run Code Online (Sandbox Code Playgroud)

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

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


更新

我尝试使用 ng-paste、ng-keypress 和 ng-keydown 仍然没有找到这个问题的答案。我试过 element.addEventListener 用于粘贴、按键和按键。我使用 jQuery 的 .on 和 .bind 没有运气。

我创建了一个重现该问题的 plunkr。

http://plnkr.co/edit/EI0otzqCZrYWCA8GgeNY?p=preview


最终更新

我找到了下面列出的解决方案,而不是使用 keypress 我使用 keyup 和 keydown 事件来检测何时按下 control 或 meta(super/windows) 键。然后我过滤掉必要的关键事件。我的最终解决方案是使用 jQuery 绑定和取消绑定事件。

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

GPr*_*ost 4

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

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

所以我想建议是使用keydown/ keyupevents 而不是keypress如果您还想监听paste事件。


一些相关问题: