Javascript - 获取任何键盘布局的键描述
Javascript - get key description for any keyboard layout
对于丰富的 Web 应用程序,我需要键盘快捷键。因为有许多不同的键盘布局,所以它们必须是可配置的。不幸的是,我想不出一种方法将键盘事件映射到 人类可读的快捷方式名称 ,例如 Ctrl + Alt + Y 或 Alt + \.
keypress
事件没有用,因为它不会触发所有键。以下是 keydown
事件的一些属性:
charCode
:仅适用于可打印字符。 已弃用,根据 MDN
code
:有效,但忽略了键盘布局。当我按 Z 键时,我的德语键盘上出现 code: "KeyY"
。
key
:有效,但根据修饰符给出不同的结果。例如Shift+3 在我的键盘上产生 key: "§"
,在大多数美式键盘上产生 key: "#"
。
keyCode
:该值不唯一。 Ä、Ö、Ü 或 ^ 产生 keyCode: 0
。 已弃用,根据 MDN
which
:与keyCode
一样,值不唯一。 已弃用,根据 MDN
altKey
、ctrlKey
、metaKey
、shiftKey
:用于检测修改键
我应该怎么做?甚至不知道用户的键盘布局也可能吗?
问题是,此时您永远无法从浏览器中知道键盘布局,您只能猜测和推测。有多种方法可以尝试某种检测,但它们总是很复杂,而不是 out-of-the-box 解决方案。
但是,您可以通过一些操作来确定按下了什么键。
所以Keydown会给你(假设事件对象是e):
e.code:保存一个字符串,标识被按下的物理键。该值不受当前键盘布局或修饰符状态影响,因此特定键将始终return相同的值。 (来自 mozilla.org)
e.key:事件所代表的键的键值。如果该值具有打印表示,则此属性的值与 char 属性相同。
e.which and e.keyCode:虽然已弃用,但会给你钥匙的位置代码在键盘上,如果 e.charCode 为 0,则这是位置代码(如果 < 256)或 unicode(这意味着键盘切换为另一种语言)
现在这里棘手的部分是 e.key 实际上表示 unicode 字符,如果它是可打印的并且不是来自美式键盘,不是特殊键。您可以将此字符转换为十进制数并检查值。如果它是一个 unicode 字符,它的十进制值将等于 which 和 keyCode 值。如果它是普通的 ASCII,它的小写值将等于 which 和 keyCode 值。此外,在执行此操作(转换)之前,您可以检查 e.key 是字符串(如 Control、Alt、CapsLock 等)还是字符(如 a、b、c 等),如果它是char,那你转换一下。
所有这些都会让您了解按下了哪个键以及该键的本机可打印字符是什么。我没有德语、意大利语或其他键盘可以测试,但你明白了。
哦,如果您担心 Shift+3 会产生“§”或“#”,您应该始终表示该组合作为 Shift+3 无论它产生什么字符,更不用说 Ctrl+Shift+[= 的组合也会产生相同的字符42=]3。您只需担心字母字符,但我相信我已经为您提供了检查的方法。
此外,我相信您可能甚至不需要 e.which 和 e.keyCode,因为e.key 应该给你一切。
我认为你的问题不是问题,只是对问题的分析不正确,你已经有了答案!
你说你想定义人类可读的快捷方式但你拒绝key
属性因为当用户按下Shift+3时,键值是§
我认为您正在等待键值为 3。
问题是“什么是人类可读的?”。
按§
得到§
或者开发者说按Shift+3按§
时得到§
不正常不是 Shift+3。
但是如果用户按下§
或Shift+3(在你的德语键盘上),键值等于§
是正常的,你可以使用keydown事件来拦截用户按下只有 3
或 §
.
在我的法语键盘上,我有一个键 é
与数字 2
在同一个键上。如果我按下 é
键(或 2),我将获得 'é' 字符。如果我按下 Shift+2(或 Shift+é)键,我会得到一个 2
字符。
我可以使用 keydown 事件拦截 Ctrl+é 和 Ctrl+2 (=Ctrl+Shift+2) 没有问题。
我认为你可以使用 keydown 事件来拦截 §
。截取 Shift+3 是不可能的,因为 shift+3 等价于 §
.
如果您的目标是独立于键盘布局拦截 SHIFT+DIGIT 键,您可以添加一些 Javascript 代码来为数字创建一些例外(或过滤器) keys (but only digit keys),我觉得其他键没必要。
这种情况可以考虑keyCode
属性拦截按键.
在所有情况下,都没有必要试图了解键盘的布局。
目前,我使用 french/french、french/belgian、french/swiss 和 american/american 键盘(或 Tastatur),我在编写 C++ ActiveControl 时遇到了同样的问题20 年前的 MFC。
如果我的回答对你来说不够好,你能post一些例子吗,这样我就可以帮助你解决这个具体的新案例。
而不是 re-inventing 轮子,我宁愿使用已经这样做的跨浏览器库
https://github.com/ccampbell/mousetrap
我无法在此处粘贴完整的 JavaScript 以避免 link 仅回答,因为 JS 超出了允许的字符数限制。
对于丰富的 Web 应用程序,我需要键盘快捷键。因为有许多不同的键盘布局,所以它们必须是可配置的。不幸的是,我想不出一种方法将键盘事件映射到 人类可读的快捷方式名称 ,例如 Ctrl + Alt + Y 或 Alt + \.
keypress
事件没有用,因为它不会触发所有键。以下是 keydown
事件的一些属性:
charCode
:仅适用于可打印字符。 已弃用,根据 MDNcode
:有效,但忽略了键盘布局。当我按 Z 键时,我的德语键盘上出现code: "KeyY"
。key
:有效,但根据修饰符给出不同的结果。例如Shift+3 在我的键盘上产生key: "§"
,在大多数美式键盘上产生key: "#"
。keyCode
:该值不唯一。 Ä、Ö、Ü 或 ^ 产生keyCode: 0
。 已弃用,根据 MDNwhich
:与keyCode
一样,值不唯一。 已弃用,根据 MDNaltKey
、ctrlKey
、metaKey
、shiftKey
:用于检测修改键
我应该怎么做?甚至不知道用户的键盘布局也可能吗?
问题是,此时您永远无法从浏览器中知道键盘布局,您只能猜测和推测。有多种方法可以尝试某种检测,但它们总是很复杂,而不是 out-of-the-box 解决方案。
但是,您可以通过一些操作来确定按下了什么键。
所以Keydown会给你(假设事件对象是e):
e.code:保存一个字符串,标识被按下的物理键。该值不受当前键盘布局或修饰符状态影响,因此特定键将始终return相同的值。 (来自 mozilla.org)
e.key:事件所代表的键的键值。如果该值具有打印表示,则此属性的值与 char 属性相同。
e.which and e.keyCode:虽然已弃用,但会给你钥匙的位置代码在键盘上,如果 e.charCode 为 0,则这是位置代码(如果 < 256)或 unicode(这意味着键盘切换为另一种语言)
现在这里棘手的部分是 e.key 实际上表示 unicode 字符,如果它是可打印的并且不是来自美式键盘,不是特殊键。您可以将此字符转换为十进制数并检查值。如果它是一个 unicode 字符,它的十进制值将等于 which 和 keyCode 值。如果它是普通的 ASCII,它的小写值将等于 which 和 keyCode 值。此外,在执行此操作(转换)之前,您可以检查 e.key 是字符串(如 Control、Alt、CapsLock 等)还是字符(如 a、b、c 等),如果它是char,那你转换一下。
所有这些都会让您了解按下了哪个键以及该键的本机可打印字符是什么。我没有德语、意大利语或其他键盘可以测试,但你明白了。
哦,如果您担心 Shift+3 会产生“§”或“#”,您应该始终表示该组合作为 Shift+3 无论它产生什么字符,更不用说 Ctrl+Shift+[= 的组合也会产生相同的字符42=]3。您只需担心字母字符,但我相信我已经为您提供了检查的方法。
此外,我相信您可能甚至不需要 e.which 和 e.keyCode,因为e.key 应该给你一切。
我认为你的问题不是问题,只是对问题的分析不正确,你已经有了答案!
你说你想定义人类可读的快捷方式但你拒绝key
属性因为当用户按下Shift+3时,键值是§
我认为您正在等待键值为 3。
问题是“什么是人类可读的?”。
按§
得到§
或者开发者说按Shift+3按§
时得到§
不正常不是 Shift+3。
但是如果用户按下§
或Shift+3(在你的德语键盘上),键值等于§
是正常的,你可以使用keydown事件来拦截用户按下只有 3
或 §
.
在我的法语键盘上,我有一个键 é
与数字 2
在同一个键上。如果我按下 é
键(或 2),我将获得 'é' 字符。如果我按下 Shift+2(或 Shift+é)键,我会得到一个 2
字符。
我可以使用 keydown 事件拦截 Ctrl+é 和 Ctrl+2 (=Ctrl+Shift+2) 没有问题。
我认为你可以使用 keydown 事件来拦截 §
。截取 Shift+3 是不可能的,因为 shift+3 等价于 §
.
如果您的目标是独立于键盘布局拦截 SHIFT+DIGIT 键,您可以添加一些 Javascript 代码来为数字创建一些例外(或过滤器) keys (but only digit keys),我觉得其他键没必要。
这种情况可以考虑keyCode
属性拦截按键.
在所有情况下,都没有必要试图了解键盘的布局。
目前,我使用 french/french、french/belgian、french/swiss 和 american/american 键盘(或 Tastatur),我在编写 C++ ActiveControl 时遇到了同样的问题20 年前的 MFC。
如果我的回答对你来说不够好,你能post一些例子吗,这样我就可以帮助你解决这个具体的新案例。
而不是 re-inventing 轮子,我宁愿使用已经这样做的跨浏览器库
https://github.com/ccampbell/mousetrap
我无法在此处粘贴完整的 JavaScript 以避免 link 仅回答,因为 JS 超出了允许的字符数限制。