如何在 Linux Chrome 中获取键修饰符
How to get key modifiers in Linux Chrome
我的 javascript 程序如何确定在 Linux 的 Chrome 中按下了哪些修饰符以及 keydown
事件?
我试过这段代码:
document.addEventListener('keydown', function(e)
{
console.log("KEY DOWN: key=" + e.key + ", code=" + e.code
+ ", meta=" + e.metaKey + ", alt=" + e.altKey);
// stop propagation, except don't kill F12.
if (e.code != 'F12')
{
e.preventDefault(); // Windows and Firefox
e.stopPropagation();
return false;
} // else: if propagating: Windows wants undefined result.
});
并且,在 Firefox 中运行时:
// output when I type M-q A-q in Firefox Quantum 67.0.4 (64-bit)
KEY DOWN: key=Meta, code=OSLeft, meta=true, alt=false
KEY DOWN: key=q, code=KeyQ, meta=true, alt=false
KEY DOWN: key=Alt, code=AltLeft, meta=false, alt=true
KEY DOWN: key=q, code=KeyQ, meta=false, alt=true
Linux Chrome 似乎受到修饰符挑战:
// output when I type M-q A-q in Linux Chrome Version 66.0.3359.181 (Official Build) (64-bit)
KEY DOWN: key=Meta, code=MetaLeft, meta=false, alt=true
KEY DOWN: key=q, code=KeyQ, meta=false, alt=true
KEY DOWN: key=Alt, code=AltLeft, meta=false, alt=true
KEY DOWN: key=q, code=KeyQ, meta=false, alt=false
显然,KeyboardEvent
的 metaKey
和 altKey
字段不是跨浏览器的。或者我没有打开 Chrome 的 "modifier keys" 功能(我该怎么做?)。或者什么的。
以上代码在 Edge 和 Chrome 在 Windows 中都工作得很好。 (Windows 将捕获 Windows 键,如果它是唯一的修饰符,但您的应用程序可以很好地捕获组合,如 Ctrl-Meta-x)。例如,当我键入 C-S-M-Q A-Q:
时,上面的代码在 Windows 中的 Edge 和 Chrome 中具有相同的输出
KEY DOWN: key=Control, code=ControlLeft, meta=false, alt=false
KEY DOWN: key=Shift, code=ShiftLeft, meta=false, alt=false
KEY DOWN: key=Meta, code=MetaLeft, meta=true, alt=false
KEY DOWN: key=Q, code=KeyQ, meta=true, alt=false
KEY DOWN: key=Alt, code=AltLeft, meta=false, alt=true
KEY DOWN: key=q, code=KeyQ, meta=false, alt=true
(注意 Chrome 和 Edge 之间的一个小区别:Edge 有 code=undefined
。但是 KeyboardEvent
中仍然有足够的信息来确定按下了哪个键,除了可能 Windows 结合 NumLock + Shift + 键盘数字有一些问题。
我上次使用 Mac,它支持 Meta 和 Alt 键,所以这个问题可能也适用于 Mac。
在 Linux 中,请确保您的计算机具有可用的 Meta 和 Alt 键,因为一些流行的发行版是开箱即用的。如果设置正确,xmodmap
应该是:
shift Shift_L (0x32), Shift_R (0x3e)
lock Caps_Lock (0x42)
control Control_L (0x25), Control_R (0x69)
mod1 Meta_L (0x85), Meta_R (0x86)
mod2 Num_Lock (0x4d)
mod3 Alt_L (0x40), Alt_R (0x6c)
mod4
mod5 ISO_Level3_Shift (0x5c), Mode_switch (0xcb)
因为程序将 mod1
解释为 Meta,将 mod3
解释为 Alt。 (使用 xev
实用程序获取键盘的键码。)使用如上所示的设置,Firefox、Emacs 和其他程序可以正确捕获所有修改键。
在 Linux Chrome 中确定与 keydown
事件一起按下的修饰符的正确方法是什么?
我认为键盘事件的最佳方法是KeyboardEvent.getModifierState()
KeyboardEvent.getModifierState() 方法 returns 指定修饰键的当前状态:如果修饰键处于活动状态则为真。
- 至少从 Firefox 48 开始,⊞ Windows 键不被视为 "Meta" 键。当按下 ⊞ Windows 时,KeyboardEvent.metaKey 为假。
参考:https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/getModifierState
此外,我总是检查 user-agent 然后我会向用户发送一个通知,告诉用户哪个密钥可用。
我想出了一些在 Chrome/Firefox/Edge 中始终有效的方法:
let modifier_challenged = /Google/.test(navigator.vendor);
let last_mod = {Meta: false, Alt: false};
function keydown(e)
{
if (modifier_challenged)
{
last_mod[e.key] = true;
e = {key: e.key,
code: e.code,
shiftKey: e.shiftKey,
ctrlKey: e.ctrlKey};
e.metaKey = last_mod['Meta'];
e.altKey = last_mod['Alt'];
}
console.log("KEY DOWN: key=" + e.key + ", code=" + e.code
+ ", meta=" + e.metaKey + ", alt=" + e.altKey);
}
function keyup(e)
{
if (modifier_challenged)
last_mod[e.key] = false;
}
document.addEventListener('keydown', keydown);
document.addEventListener('keyup', keyup);
但我更喜欢一个答案,如果最近按下或释放修饰符 在 window 之外 (在键盘焦点移回 window).也许不可能?
更新
好吧,如果你一次只使用一个修饰符,上面的代码就没问题。但是如果你想组合许多修饰符,Chrome 仍然有问题......如果你还按住 Shift 键,它会将 key
值从 Alt 更改为 Meta。所以我们必须使用:
let modif_codes = /^Control|^Shift|^Meta|^Alt|^OS/;
function set_last_mod(e, value)
{
if (!modif_codes.test(e.key))
return;
let key_sym = e.code.replace(/([A-Z])/g, " ").split(" ")[1];
if (key_sym != e.key)
{
console.log("Warning: code(" + e.code
+ ") does not match key(" + e.key
+ "). Using " + key_sym + ".");
}
last_mod[key_sym] = value;
}
代替last_mod[e.key] = value
。
我的 javascript 程序如何确定在 Linux 的 Chrome 中按下了哪些修饰符以及 keydown
事件?
我试过这段代码:
document.addEventListener('keydown', function(e)
{
console.log("KEY DOWN: key=" + e.key + ", code=" + e.code
+ ", meta=" + e.metaKey + ", alt=" + e.altKey);
// stop propagation, except don't kill F12.
if (e.code != 'F12')
{
e.preventDefault(); // Windows and Firefox
e.stopPropagation();
return false;
} // else: if propagating: Windows wants undefined result.
});
并且,在 Firefox 中运行时:
// output when I type M-q A-q in Firefox Quantum 67.0.4 (64-bit)
KEY DOWN: key=Meta, code=OSLeft, meta=true, alt=false
KEY DOWN: key=q, code=KeyQ, meta=true, alt=false
KEY DOWN: key=Alt, code=AltLeft, meta=false, alt=true
KEY DOWN: key=q, code=KeyQ, meta=false, alt=true
Linux Chrome 似乎受到修饰符挑战:
// output when I type M-q A-q in Linux Chrome Version 66.0.3359.181 (Official Build) (64-bit)
KEY DOWN: key=Meta, code=MetaLeft, meta=false, alt=true
KEY DOWN: key=q, code=KeyQ, meta=false, alt=true
KEY DOWN: key=Alt, code=AltLeft, meta=false, alt=true
KEY DOWN: key=q, code=KeyQ, meta=false, alt=false
显然,KeyboardEvent
的 metaKey
和 altKey
字段不是跨浏览器的。或者我没有打开 Chrome 的 "modifier keys" 功能(我该怎么做?)。或者什么的。
以上代码在 Edge 和 Chrome 在 Windows 中都工作得很好。 (Windows 将捕获 Windows 键,如果它是唯一的修饰符,但您的应用程序可以很好地捕获组合,如 Ctrl-Meta-x)。例如,当我键入 C-S-M-Q A-Q:
时,上面的代码在 Windows 中的 Edge 和 Chrome 中具有相同的输出KEY DOWN: key=Control, code=ControlLeft, meta=false, alt=false
KEY DOWN: key=Shift, code=ShiftLeft, meta=false, alt=false
KEY DOWN: key=Meta, code=MetaLeft, meta=true, alt=false
KEY DOWN: key=Q, code=KeyQ, meta=true, alt=false
KEY DOWN: key=Alt, code=AltLeft, meta=false, alt=true
KEY DOWN: key=q, code=KeyQ, meta=false, alt=true
(注意 Chrome 和 Edge 之间的一个小区别:Edge 有 code=undefined
。但是 KeyboardEvent
中仍然有足够的信息来确定按下了哪个键,除了可能 Windows 结合 NumLock + Shift + 键盘数字有一些问题。
我上次使用 Mac,它支持 Meta 和 Alt 键,所以这个问题可能也适用于 Mac。
在 Linux 中,请确保您的计算机具有可用的 Meta 和 Alt 键,因为一些流行的发行版是开箱即用的。如果设置正确,xmodmap
应该是:
shift Shift_L (0x32), Shift_R (0x3e)
lock Caps_Lock (0x42)
control Control_L (0x25), Control_R (0x69)
mod1 Meta_L (0x85), Meta_R (0x86)
mod2 Num_Lock (0x4d)
mod3 Alt_L (0x40), Alt_R (0x6c)
mod4
mod5 ISO_Level3_Shift (0x5c), Mode_switch (0xcb)
因为程序将 mod1
解释为 Meta,将 mod3
解释为 Alt。 (使用 xev
实用程序获取键盘的键码。)使用如上所示的设置,Firefox、Emacs 和其他程序可以正确捕获所有修改键。
在 Linux Chrome 中确定与 keydown
事件一起按下的修饰符的正确方法是什么?
我认为键盘事件的最佳方法是KeyboardEvent.getModifierState()
KeyboardEvent.getModifierState() 方法 returns 指定修饰键的当前状态:如果修饰键处于活动状态则为真。
- 至少从 Firefox 48 开始,⊞ Windows 键不被视为 "Meta" 键。当按下 ⊞ Windows 时,KeyboardEvent.metaKey 为假。
参考:https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/getModifierState
此外,我总是检查 user-agent 然后我会向用户发送一个通知,告诉用户哪个密钥可用。
我想出了一些在 Chrome/Firefox/Edge 中始终有效的方法:
let modifier_challenged = /Google/.test(navigator.vendor);
let last_mod = {Meta: false, Alt: false};
function keydown(e)
{
if (modifier_challenged)
{
last_mod[e.key] = true;
e = {key: e.key,
code: e.code,
shiftKey: e.shiftKey,
ctrlKey: e.ctrlKey};
e.metaKey = last_mod['Meta'];
e.altKey = last_mod['Alt'];
}
console.log("KEY DOWN: key=" + e.key + ", code=" + e.code
+ ", meta=" + e.metaKey + ", alt=" + e.altKey);
}
function keyup(e)
{
if (modifier_challenged)
last_mod[e.key] = false;
}
document.addEventListener('keydown', keydown);
document.addEventListener('keyup', keyup);
但我更喜欢一个答案,如果最近按下或释放修饰符 在 window 之外 (在键盘焦点移回 window).也许不可能?
更新
好吧,如果你一次只使用一个修饰符,上面的代码就没问题。但是如果你想组合许多修饰符,Chrome 仍然有问题......如果你还按住 Shift 键,它会将 key
值从 Alt 更改为 Meta。所以我们必须使用:
let modif_codes = /^Control|^Shift|^Meta|^Alt|^OS/;
function set_last_mod(e, value)
{
if (!modif_codes.test(e.key))
return;
let key_sym = e.code.replace(/([A-Z])/g, " ").split(" ")[1];
if (key_sym != e.key)
{
console.log("Warning: code(" + e.code
+ ") does not match key(" + e.key
+ "). Using " + key_sym + ".");
}
last_mod[key_sym] = value;
}
代替last_mod[e.key] = value
。