国际键盘如何处理 JavaScript 键盘事件

How do international keyboards work with JavaScript keyboard events?

本文关键字:键盘 处理 JavaScript 事件 何处理      更新时间:2023-09-26

我用JavaScript编写了一个文本编辑器,它直接绘制到Canvas元素(出于各种原因,但我的主要原因是我可以将该画布作为纹理拍打到WebGL网格上)。令人惊喜的是,实现我找到的任何内容可编辑解决方案都更容易。

我早期注意到的一件事是,使用en-US QWERTY以外的键盘布局的人抱怨某些键显示不正确的字母。在对Windows的语言设置和屏幕键盘进行了一些摆弄之后,我创建了一个基于代码页的解决方案,该解决方案将keyCodes直接映射到不同语言环境的字符串,而不仅仅是假设"没有修饰键的keyCode 51是数字3"。因为它不是,在某些键盘上它是双qoute。

但仍然有一些奇怪之处。几个示例(请注意,所有这些示例都基于使用 Windows 屏幕键盘,因此我仅假设这与现实相关):

  • 法语 AZERTY 键盘在键入字母 U 时发送 keyDown 和 keyPressed 事件,但从不发送 keyUp。我假设 U 必须与另一个键结合使用,但不知道正确的行为应该是什么会阻止我编写正确的代码。编辑:我还没有完全弄清楚这意味着什么,除了 - 也许 - 那个键只用于整个法语的一个词?
  • 德语 QWERTZ 键盘有一个 ^(它不是插入符号,它看起来更大)键,其中 ' (反引号) 键将位于美国键盘上,以及一个反引号键,其中 =(等于)键将位于美国键盘上。在这两种情况下,它们都会发送 keyDown 和 keyUp 事件,但在我使用的任何文本编辑器中似乎都不会打印任何内容,直到它们被第二次点击,然后打印两个字符。这与组合标记有关吗?我找不到任何关于它的信息。 编辑:这些被称为死键,它们创建重音字母。很多键盘布局都有它们。我将为此创建一个按键排序系统,它还将有助于为更复杂的 Emacs 风格的键盘快捷键提供支持(如果选择了任何快捷键)。
  • 英国QWERTY键盘有一个反斜杠,需要使用ALT-GRAPH键(美国键盘上的右Alt键)。KeyboardEvent 有一个位置属性,可用于确定按下了哪些 ALT 键,但它显然在 Safari 中不可用。这是相当低的优先级,因为 Safari 通常只占我流量的 1% 或更少。但是,是否有适用于 Safari 的属性可以用作后备? 编辑:我将处理这个问题,因为我的代码页系统的其余部分适用于小写和大写键之间的差异。它只是新修饰键的不同代码页。我将不得不更改检测修饰键的方式,但这是一个很小的更改,实际上很容易适应键盘快捷键系统。
  • 最后,从Windows的语言设置来看,世界上有很多不同的键盘布局。是否有任何地方的键码和行为列表?我宁愿不必手动测试每个键盘,只是为了为它们生成新的代码页。

前两个问题是最大的。如果我只知道行为应该是什么,我就可以找出解决这些问题的方法。第三个问题将适合我的代码页系统,尽管我必须更改读取修饰键的方式。最后一个问题,我可能会付钱给某人来报道。

而且我无法在 100% 的时间内为所有浏览器中的所有用户解决它。但我遇到的大多数信息基本上都是"不要打扰",这实际上听起来更像是"我不知道"。

编辑:选择布局不是问题。如果事情不适合他们,我会将其作为选项提供给用户。我认为这是在这种情况下可以做的最好的事情,但显然我会自动检测是否可以。我真的只关心获得正确的行为,因为已经选择了正确的布局。

我想避免任何涉及keyPress事件的事情,因为它并不完全可靠。如果我有关于键盘布局的可靠数据源,那就不是问题了。

您无法获取键盘布局...

没有办法(使用纯JS解决方案)检测用户的键盘布局。

请注意,"en-US"或"en-GB"不会映射到这些语言的任何特定/商定的键盘布局。用户的语言与其键映射到字符的方式无关。

您可以根据他们的区域设置/语言代码做出假设,但这并不能提供任何保证 - 它只会增加您迎合适当布局的可能性。

另请参阅以下问题:

将 Javascript 键代码转换为非美国键盘布局(即 azerty)的字符代码

使用 JavaScript 检测键盘布局

。但是你可以用它输入字符:

但是,根据您所需的浏览器支持(使用 canvas 应该相当不错),您可以尝试使用 charCode 属性:

http://www.w3schools.com/jsref/event_key_charcode.asp

var unicodeCharCode = e.charCode;

请注意,这不会返回实际字符 - 您将获得代表它的数字(不是键):

Unicode 字符代码是一个字符的编号(例如 数字"97"代表字母"A")。

您可以根据需要轻松地将这些代码映射到字符,或者只使用内置函数:

var userInput = String.fromCharCode(unicodeCharCode);
  • 聪明/为自己工作,你也可以(相当微不足道地)编写一个库来猜测某些键代码返回的字符代码的键盘布局。不要:)

替代方法:

用作解决方法的一个建议是使用隐藏(或至少离散)文本输入/文本框,您的应用设置将重点关注该文本框。

当您的应用检测到按键/按键等时,您可以获取用户输入的值并将其呈现在画布上。

由于您已经在捕获键盘事件,因此处理组合应该很容易(如有必要)。在某些方面,甚至不需要这样做,因为您只需要监视用户输入的输入长度(您的应用程序不必关心用户是否需要三键组合来输入字符,您只需获取结果)。