在Firefox和&amp ;;中,keypress和keydown优先于粘贴事件。的Safari

时间:2017-03-09 22:21:24

标签: javascript jquery angularjs

我有一个使用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时,有没有办法防止在Firefox和Safari上触发/调用keydown和keypress事件?

更新

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

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

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

最终更新

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

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

1 个答案:

答案 0 :(得分:3)

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

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

所以我想如果您还想听paste事件,建议使用keydown / keyup个事件代替keypress

一些相关问题:

相关问题