在Firefox中它可以工作,因为Firefox会为任何密钥触发按键事件.这很舒服但是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.
我不同意该规范,因为我认为没有理由.但就像现在一样,我无能为力.
问题是Google Chrome遵循该规范,并且不会触发按键功能键.但是,它确实会对所有按键进行正常启动.
我的程序只有一个键事件处理程序.它期望事件包含keyCode(物理键的ID和可选的charCode,等效字符值(对于有意义的键).
keydown事件在两个浏览器中都不包含任何字符值!它只包含keyCode.因此,如果您定义了Ctrl Z组合并侦听keydown事件,那么对于具有QWERTZ布局的用户,您的程序将被破坏 – 因为密钥的物理位置(keyCode)仍然相同.
如果你同时监听keydown和keypress,那么角色事件将会触发两次(因为首先触发keydown然后使用正确的charCode属性触发按键)
我需要的?
基于以上所述,我需要忽略将导致按键的键的keydown事件.这样做,我将能够在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; });
我想我花了很多时间制作JSFiddles并没有真正增加获得答案的几率,所以我改为上传了实际的项目.
单击Firefox中的白色方块,按T键,键入文本,按Esc键,按Esc键.秒Esc后,光标应恢复正常.尝试绘制并按Ctrl Z.
在Google Chrome中重复此过程. Escape不起作用,因为它不会触发按键.出于某种原因,Ctrl Z使用keyCode 26触发事件.
来自聊天和评论:
@someDoge has created a fiddle我已经扩展了,现在很好地展示了这种情况.正如您所看到的,您可以知道密钥不是字符,而是在按键中忽略它.但你不能知道tab不是字符并在keydown中取消它(除非你在注释中有@someDoge sugest的固定数组的键码值).