javascript - OS X 上的 JS 键码:当“空格”+另一个键已经被按下时,“Digit6”不会被触发
问题描述
当“Space”(或“Slash”、“KeyH”以及可能其他)+另一个随机键(比如“Digit5”)已被按下时,不会触发“Digit6”。
- 保持(空格键+键 5)并按下键 4返回 event.code “Digit4”
- 保持(空格键+键 5)并按下键 6仍会返回 event.code “Digit5”(因此没有任何反应)。
我在 Chrome、Safari、Firefox 中尝试了这个测试,结果是一样的。我也在 Windows 10 上尝试过它,它按预期工作,所以我猜它可能是 OS X 的东西。
解决方案
在此处添加完整的答案以防万一其他人遇到此问题,但对于您的具体问题,请查看最后。
有KeyboardEvent
几个不同的属性可以帮助您找出按下了哪些键:
e.which
,e.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 个修饰键,如下所示:
如果您打开控制台,您可以看到KeyboardEvents
正在记录的个人。
问题在于,KeyboardEvent
唯一包含有关已按下或释放的最后一个键的信息(4 个修饰键除外),并且https://keyjs.dev和https://keycode.info都在一次,因此您需要使用keydown
andkeyup
事件来跟踪自己按下/释放的内容:
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。但是,某些键盘可能具有下限或对键进行不同的编码,根据键的特定组合具有下限或上限,因此您可能正在其中一种情况下运行。
推荐阅读
- react-native - 如何过滤 JSON 响应并从中获取所需的数据?
- extjs - ExtJS 7.4(现代工具包),网格标题菜单复选框在选择后无法取消选择(带有过滤器值)
- powershell - 跟踪 RDP 会话的整个历史记录
- c# - 如何在我的 ASP.NET CORE 5 应用程序中清理我的控制器操作和引用?
- java - 调用特定的构造函数来映射@requestBody
- python - 从张量图像(归一化在 0 到 1 之间)到 0 到 255 之间的像素
- javascript - 如何在MongoDB中将所有文档的数组字段组合在一起?
- pom.xml - 我在 pom.xml 的第一行得到红色 X 标记...我想知道原因
- sql-server - SSRS 多选和 For-Each 存储过程
- react-native - 如何将Unity游戏导出为React Native?