Javascript - 获取任何键盘布局的关键描述

时间:2018-03-01 18:50:14

标签: javascript events keyboard-shortcuts keyboard-events

对于富Web应用程序,我需要键盘快捷键。因为有许多不同的键盘布局,所以它们必须是可配置的。不幸的是,我无法找到一种方法将键盘事件映射到人类可读的快捷方式名称,例如 Ctrl + Alt + Y Alt + \

keypress事件没用,因为它不会触发所有键。以下是keydown事件的一些属性:

  • charCode:仅适用于可打印字符。根据MDN
  • 已弃用
  • code:工作,但忽略键盘布局。当我按Z键时,我的德语键盘上显示code: "KeyY"
  • key:有效,但根据修饰符给出不同的结果。 E. g。 Shift + 3在键盘上产生key: "§",在大多数美国键盘上产生key: "#"
  • keyCode:该值不是唯一的。 Ä,Ö,Ü或^产生keyCode: 0。根据MDN
  • 已弃用
  • which:就像keyCode一样,该值不是唯一的。根据MDN
  • 已弃用
  • altKeyctrlKeymetaKeyshiftKey:用于检测修饰键

我该怎么做?在不知道用户键盘布局的情况下甚至可以吗?

3 个答案:

答案 0 :(得分:3)

问题是,在这个时间点你永远无法从浏览器中知道键盘布局,你只能猜测和推测。有多种方法可以尝试某种检测,但它们总是很复杂,而且不是开箱即用的解决方案。

但是,您可以采取一些措施来确定按下了哪个键。

所以Keydown会给你(说事件对象是e):

e.code :包含一个标识正在按下的物理键的字符串。值不受当前键盘布局或修改器状态的影响,因此特定键将始终返回相同的值。 (来自mozilla.org)

e.key :事件代表的键的键值。如果值具有打印表示,则此属性的值与 char 属性相同。

e.which e.keyCode :虽然已弃用,但会为您提供键盘上键的位置代码,如果e.charCode为0,则这是位置代码(如果< 256)或unicode(这意味着键盘用另一种语言切换)

现在,棘手的部分是 e.key 实际上代表 unicode 字符,如果它是可打印的并且不是来自美国键盘且不是特殊键。您可以将此字符转换为十进制数并检查该值。如果它是一个unicode字符,它的十进制值将等于which和keyCode值。如果是普通ASCII,则它的小写值将等于which和keyCode值。此外,在执行此操作(转换)之前,您可以检查e.key是否为字符串(如Control,Alt,CapsLock等)或char(如a,b,c等)。所以如果它是char,然后你转换它。

所有这些都可以让您了解按下了哪个键以及该键的原生可打印字符是什么。我没有德语,意大利语或其他键盘来测试,但你明白了。

哦,如果你担心 Shift + 3 产生“§”或“#”,你应该总是将该组合表示为Shift + 3而不管角色它产生,并不是说用 Ctrl + Shift + 3 的组合产生相同的效果。你只需要担心字母字符,但我相信我给了你检查它的方法。

此外,我相信你甚至可能不需要 e.which e.keyCode ,因为 e.key 应该给出你应有尽有。

答案 1 :(得分:2)

我认为您的问题不是问题,只是对问题的错误分析并且您已经得到答案了!

您说要定义人类可读的快捷方式并拒绝key属性,因为当用户按Shift + 3时,键值为§,我认为您等待该键值为3。

问题是“什么是人类可读?”。

§并获取§或开发人员表示不正常当他按Shift + 3时按§,他获得§而不是Shift 3。

但是如果用户按下§或Shift + 3(在德语键盘上),则键值等于§是正常的,并且当用户仅按下时,您可以使用keydown事件进行拦截{ {1}}或3

在我的法语键盘上,我有一个键§与数字é在同一个键上。如果我按下键2(或2),我会获得'é'字符。如果我按Shift + 2(或Shift +é)键,我会获得一个é字符。

我可以使用keydown事件拦截Ctrl +é和Ctrl + 2(= Ctrlt + Shift + 2)而没有问题。

我认为您可以使用keydown事件来拦截2。拦截Shift + 3是不可能的,因为shift + 3相当于§

如果你的目标是独立于键盘布局拦截SHIFT + DIGIT键,你可以添加一些Javascript代码来为数字键创建一些例外(或过滤器)(但只有数字键),我认为没有必要使用其他密钥。

在这种情况下,您可以考虑§属性来拦截按下数字键

在所有情况下,尝试了解键盘的布局都没有必要。

目前,我使用法语/法语,法语/比利时语,法语/瑞士语和美国/美国键盘(或Tastatur),我在20年前使用MFC编写C ++ ActiveControl时遇到了同样的问题。

如果我的答案对您不够好,您可以发布一些示例,以便我可以帮助您解决这些特定的新案例。

答案 2 :(得分:1)

我宁愿使用已经做过那种

的跨浏览器库,而不是重新发明轮子

https://github.com/ccampbell/mousetrap

我无法在此处粘贴完整的JavaScript以避免链接唯一的答案,因为如果允许的字符,JS超出限制。