我有一个使用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
答案 0 :(得分:3)
好的,我想我找到了一些关于这个问题的信息。与keydown
事件相比,keypress
只应在按下显示字符的键时触发:字母,数字等(可打印键)。但问题是keypress
事件没有官方规范,因此浏览器以不同方式实现它。例如,在Chrome cmd + v
命令中不会触发keypress
事件,但在Firefox和Safari中它会(就像您只按v
键一样)并且它会以某种方式中断{{1命令,所以它不会触发。
如果您尝试通过上下文菜单将文字粘贴到输入中,您会发现它工作正常。
所以我想如果您还想听paste
事件,建议使用keydown
/ keyup
个事件代替keypress
。
一些相关问题: