如何判断keydown是否会导致按键事件,在这种情况下会忽略它?

时间:2014-12-02 16:41:32

标签: javascript events keyboard-events

我对javascript中的关键事件不是很满意。我需要捕获两个写字母(我在<canvas>上写文字)和其他命令的功能键(转义)。

在Firefox中可行,因为Firefox会为任何键触发keypress事件。这很舒服,但specification directly permits it

  

如果用户代理支持,则必须在按下某个键时调度此事件,当且仅当该键通常产生字符值时才会发送。

我不同意该规范,因为我认为没有理由。但就像现在一样,我对此无能为力。

问题是Google Chrome遵循该规范,并且不会针对功能键触发keypress。但是,它确实会为所有密钥发送keydown

我的程序只有一个关键事件处理程序。它期望事件包含keyCode(物理密钥的ID和可选 charCode,等效字符值(对于有意义的密钥)。

keydown事件在两个浏览器中都不包含任何字符值!它只包含keyCode。因此,如果您定义 Ctrl + Z 组合并监听keydown事件,那么对于拥有QWERTZ的用户,您的程序将被破坏布局 - 因为密钥(keyCode)的物理位置仍然相同。

如果您同时收听keydownkeypress,则字符事件将触发两次(因为首先触发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中的白色方块,按 T ,输入文字,按 Esc ,按 Esc 。在秒 Esc 之后,光标应该恢复正常。尝试绘制并按 Ctrl + Z

在Google Chrome中重复此过程。 Escape不起作用,因为它不会触发keypress。出于某种原因, Ctrl + Z 会使用keyCode 26来触发事件。

来自聊天和评论:

@someDoge has created a fiddle我已经扩展了,现在很好地展示了这种情况。如您所见,您可以知道键不是字符并在按键中忽略它。但你不能知道 tab 不是字符并在keydown中取消它(除非你在注释中有@someDoge sugest的固定数组的键码值)。

1 个答案:

答案 0 :(得分:2)

您需要监听keyup个事件而不是keydown,这样您就不会生成两个单独的事件。

然后,您可以使用相同的处理函数处理2个事件类型,这些函数将获得charCode,具体取决于特定键是否生成了“keypress”事件。只要你防止冒泡,你的处理程序只会被调用一次。

关于Chrome CTRL + Z问题:如果按下控制键,我看不到如何获取charCode,因为它似乎只会生成一个keyup事件。