javascript - 我怎么知道 keydown 会导致 keypress 事件,在那种情况下忽略它?

标签 javascript events keyboard-events

我对 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) 仍然相同。

如果您同时收听 keydownkeypress , Angular 色事件将触发两次(因为 Angular 色首先触发 keydown 然后 keypress 具有适当的 charCode 属性)

我需要什么?

基于以上,我需要忽略keydown将导致 keypress 的键事件.这样做,我将能够在 keydown 中捕获 Esckeypress 中的字符.

我怎么可能做到?

相关代码:

  //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,按EscEsc 秒后,光标应恢复正常。尝试绘制并按 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/

相关文章:

javascript - 如何将事件处理程序分配给 proto.io 开/关开关?

javascript - Javascript 如何控制事件

Angular 2 同级组件之间的通信

macos - 没有标题栏就没有键盘捕获

javascript - d3.js 多个圆环图

javascript - 使用导入的 csv 文件中的 java 脚本更改日期格式

javascript - JQuery 仅在初次按下时读取事件键?

javascript - 禁用 html5 页面内 svg 的键盘事件

javascript - 类型错误 : Cannot read property of undefined with web-sockets

javascript - 为什么我的 onClick 事件没有在 React 上触发?