我对 javascript 中的关键事件不是很满意。我需要捕获用于书写的字母(我正在 <canvas>
上书写文本)和用于其他命令的功能键(转义)。
在 Firefox 中它可以工作,因为 Firefox 会触发 keypress
任何键的事件。很舒服但是specification directly permits it :
If supported by a user agent, this event MUST be dispatched when a key is pressed down, if and only if that key normally produces a character value.
我不同意该规范,因为我认为没有理由这样做。但事已至此,我也无能为力。
问题是谷歌浏览器遵循该规范并且不会触发 keypress
用于功能键。但是,它确实不会触发 keydown
对于所有键。
我的程序只有一个键事件处理程序。它期望包含 keyCode
的事件(物理键的 ID 和可选 charCode
,等效字符值(对于有意义的键)。
keydown
事件在两个浏览器中都不包含任何字符值!它只包含 keyCode
.因此,如果您定义 Ctrl+Z 组合并监听 keydown
事件,对于具有 QWERTZ 布局的用户,您的程序将被破坏 - 因为键的物理位置 (keyCode
) 仍然相同。
如果您同时收听 keydown
和 keypress
, Angular 色事件将触发两次(因为 Angular 色首先触发 keydown
然后 keypress
具有适当的 charCode
属性)
我需要什么?
基于以上,我需要忽略keydown
将导致 keypress
的键事件.这样做,我将能够在 keydown
中捕获 Esc和 keypress
中的字符.
我怎么可能做到?
相关代码:
//Keypress for character codes
div.addEventListener("keypress", function(event) {
console.log(event);
if(_this.editor.event(event)) {
console.log("Event canceled.");
event.preventDefault();
event.cancelBubble = true;
return false;
}
return true;
});
//Keydown for Esc and the likes
div.addEventListener("keydown", function(event) {
//Character events are handled by keypress
if(event.charCode!=0) //Does NOT work - in keydown, charCode is ALLWAYS 0
return true;
console.log(event);
if(_this.editor.event(event)) {
console.log("Event canceled.");
event.preventDefault();
event.cancelBubble = true;
return false;
}
return true;
});
Interactive example
我想我花了很多时间制作 JSFiddles,但它并没有真正增加得到答案的几率,所以我上传了实际的项目。
点击Firefox中的白色方 block ,按T,输入文字,按Esc,按Esc。 Esc 秒后,光标应恢复正常。尝试绘制并按 Ctrl+Z。
在谷歌浏览器中重复该过程。 Escape 不会工作,因为它不会触发 keypress
.出于某种原因,Ctrl+Z 触发事件 keyCode
26.
来自聊天和评论:
@someDoge has created a fiddle我已经扩展了它,现在很好地说明了情况。如您所见,您可以知道某个键不是字符并在按键中忽略它。但是你不能知道 tab 不是字符并在 keydown
中取消它(除非您有固定的键码值数组,如@someDoge 在评论中建议的那样)。
最佳答案
您需要监听 keyup
事件而不是 keydown
,这样您就不会生成两个单独的事件。
然后您可以使用相同的处理函数处理这两种事件类型,该处理函数将获取或不获取 charCode,具体取决于特定键是否生成了“按键”事件。只要您防止冒泡,您的处理程序就只会被调用一次。
关于 Chrome CTRL+Z 问题:如果按下控制键,我看不出如何获取 charCode,因为它似乎只生成一个 keyup 事件。
关于javascript - 我怎么知道 keydown 会导致 keypress 事件,在那种情况下忽略它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27254507/