首页 > 解决方案 > OS X 上的 JS 键码:当“空格”+另一个键已经被按下时,“Digit6”不会被触发

问题描述

当“Space”(或“Slash”“KeyH”以及可能其他)+另一个随机键(比如“Digit5”)已被按下,不会触发“Digit6”。

https://keycode.info示例:

  1. 保持(空格键+键 5)并按下键 4返回 event.code “Digit4”
  2. 保持(空格键+键 5)并按下键 6仍会返回 event.code “Digit5”(因此没有任何反应)。

我在 Chrome、Safari、Firefox 中尝试了这个测试,结果是一样的。我也在 Windows 10 上尝试过它,它按预期工作,所以我猜它可能是 OS X 的东西。

标签: javascriptmacoskeycode

解决方案


在此处添加完整的答案以防万一其他人遇到此问题,但对于您的具体问题,请查看最后。

KeyboardEvent几个不同的属性可以帮助您找出按下了哪些键:

  • ✏️e.key并且e.code是指刚刚按下/释放的键的新属性。

  • e.whiche.keyCode并且e.charCode是用于同一事物的旧的弃用属性,但不应再使用(除非您出于某种原因需要支持非常旧的浏览器)。

  • altKey, ctrlKey, metaKey,shiftKey表示如果⌥</kbd>, ⌃</kbd>, ⌘</kbd> or ⇧</kbd> keys, respectively, were pressed together with the main key (e.key / e.code), assuming this one was pressed before.

    这意味着如果你按下⇧</kbd> + J (in this order), then you'll get { e.key: "J", e.shiftKey: true } in the second event (you get one per key) but if you press J + ⇧</kbd> (in this order), then you'll get { e.key: "J", e.shiftKey: false } followed by { e.key: "Shift", e.shiftKey: true }.

这些是它在按下时包含的所有属性⇧</kbd> + J:

{
    altKey: false, ️
    bubbles: true,
    cancelBubble: false,
    cancelable: true,
    charCode: 0, 
    code: "KeyJ", ✏️
    composed: true,
    ctrlKey: false, ️
    currentTarget: null,
    defaultPrevented: false,
    detail: 0,
    eventPhase: 0,
    isComposing: false,
    isTrusted: true,
    key: "J", ✏️
    keyCode: 74, 
    location: 0,
    metaKey: false, ️
    path: (5) [input#input, body, html, document, Window],
    repeat: false,
    returnValue: true,
    shiftKey: true, ️
    sourceCapabilities: InputDeviceCapabilities { firesTouchEvents: false },
    srcElement: input#input,
    target: input#input,
    timeStamp: 10280.554999997548,
    type: "keydown",
    view: Window { … },
    which: 74, 
}

如果你去https://keyjs.dev免责声明:我是作者。)你会看到它实际上检测到任何键以及同时按下的 4 个修饰键,如下所示:

Key.js \ JavaScript KeyboardEvent 的键码和键标识符

如果您打开控制台,您可以看到KeyboardEvents正在记录的个人。

问题在于,KeyboardEvent唯一包含有关已按下或释放的最后一个键的信息(4 个修饰键除外),并且https://keyjs.devhttps://keycode.info都在一次,因此您需要使用keydownandkeyup事件来跟踪自己按下/释放的内容:

const pressedKeys = {};

function logPressedKeys() {
  console.log(Object.keys(pressedKeys).join(' + '));
}

document.addEventListener('keydown', ({ key, altKey, ctrlKey, metaKey, shiftKey }) => {
  pressedKeys[key] = true;
  
  if (altKey) pressedKeys.Alt = true;
  if (ctrlKey) pressedKeys.Control = true;
  if (metaKey) pressedKeys.Meta = true;
  if (shiftKey) pressedKeys.Shift = true;
  
  logPressedKeys();
});

document.addEventListener('keyup', ({ key, altKey, ctrlKey, metaKey, shiftKey }) => {
  delete pressedKeys[key];
  
  if (!altKey) delete pressedKeys.Alt;
  if (!ctrlKey) delete pressedKeys.Control;
  if (!metaKey) delete pressedKeys.Meta;
  if (!shiftKey) delete pressedKeys.Shift;
  
  logPressedKeys();
});

请注意,同时按下键盘可以检测到多少个键也有硬件限制。就我而言,这是 6。但是,某些键盘可能具有下限或对键进行不同的编码,根据键的特定组合具有下限或上限,因此您可能正在其中一种情况下运行。


推荐阅读