国际键盘如何与JavaScript键盘事件配合工作?

6
我已经用JavaScript编写了一个直接绘制到Canvas元素的文本编辑器(出于各种原因,但我的主要原因是我可以将该画布放在WebGL网格上作为纹理)。 令人愉快的惊喜是,它比我找到的任何可编辑内容解决方案都更容易实现。
我早期注意到的一件事是,使用en-US QWERTY以外的键盘布局的人们抱怨某些键显示错误的字母。 经过一些Windows语言设置和屏幕键盘的摆弄后,我创建了基于代码页的解决方案,直接将不同区域设置的keyCode映射到字符串,而不仅仅是假定“没有修改键的keyCode 51是数字3”。 因为在某些键盘上,它是双引号。
但仍然存在一些奇怪之处。以下是一些示例(请注意,这些示例都基于使用Windows屏幕键盘,因此我只是假设这与现实相关):
  • 法语 AZERTY 键盘在键入字母 U 时会发送 keyDown 和 keyPressed 事件,但从未发送 keyUp。我猜 U 必须与另一个键组合使用,但由于不知道正确的行为是什么,因此无法编写正确的代码。编辑:我还没有完全弄清楚这意味着什么,除了——也许——该键仅在整个法语中用于一个单词之外?
  • 德语 QWERTZ 键盘有一个 ^(它不是插入符号,它看起来更大)键,在美国键盘上会出现 `(反引号)键,并且反引号键在 =(等于)键应该在美国键盘上出现的位置。在这两种情况下,它们都发送 keyDown 和 keyUp 事件,但在我使用的任何文本编辑器中似乎都不会打印任何内容,直到第二次按下它们,然后打印两个字符。这与组合标记有关吗?我找不到任何相关信息。编辑:这些被称为死键,它们可以创建带重音符号的字母。许多键盘布局都有它们。我将为此创建一个按键序列系统,该系统还将帮助提供更复杂的 Emacs 风格键盘快捷键支持,如果选择了任何键盘快捷键。
  • 英国 QWERTY 键盘有一个反斜杠,需要使用 ALT-GRAPH 键(在美国键盘上为右 Alt 键)。有一个 KeyboardEvent 的 location 属性 可以用于确定按下哪个 ALT 键,但它似乎在 Safari 中不可用。这非常低优先级,因为 Safari 通常仅占我的流量的 1%或更少。但是,是否有适用于 Safari 的属性可以用作后备?编辑:我将像我的其余代码页系统一样处理此问题,以处理小写和大写键之间的差异。这只是一个新修饰符键的不同代码页。我将不得不更改如何检测修饰键,但这是一个次要更改,并且实际上非常容易适应键盘快捷键系统。
  • 最后,从 Windows 的语言设置来看,世界上有很多不同的键盘布局。是否有任何键码和行为的列表?我不想手动测试每个键盘以生成新的代码页。
第一个和第二个问题是最大的。如果我知道预期的行为,我就能想出解决方案。第三个问题将适应我的代码页系统,但我必须改变读取修改键的方式。最后一个问题,我可能可以支付别人来解决。
我不介意不能在所有浏览器中为所有用户100%解决问题。但我遇到的大部分信息基本上是“不要费心了”,这实际上只听起来更像“我不知道”。
编辑:选择布局并不是一个问题。我将其作为选项提供给用户,如果对他们不起作用。我认为这是在这种情况下可以做的最好的事情,但显然,如果我能自动检测就更好了。我只关心在已经选择正确布局的情况下获得正确的行为。
我希望避免涉及keyPress事件的任何事情,因为它并不完全可靠。如果我有一个可靠的键盘布局数据来源,那就不是问题了。
1个回答

10

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

(使用纯JS方案)无法检测用户的键盘布局。

请注意,“en-US”或“en-GB”不对应这些语言的任何特定/约定的键盘布局。用户的语言与他们的按键映射到字符的方式无关。

您可以基于他们的区域设置/语言代码进行假设,但这并不能提供任何保证-它只是增加了为适当的布局服务的可能性。

另请参阅以下问题:

将JavaScript keyCode翻译为非美国键盘布局(即AZERTY)的charCode

使用JavaScript检测键盘布局

...但是您可以获取输入的字符:

但是,根据所需的浏览器支持情况(使用画布,应该相当好),您可以尝试使用charCode属性:

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

var unicodeCharCode = e.charCode;

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

Unicode字符代码是一个字符的编号(例如,数字“97”表示字母“a”)。

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

var userInput = String.fromCharCode(unicodeCharCode);
  • 如果你很聪明 / 想自己动手,你也可以(相当简单地)编写一个库来猜测从特定keyCode返回的charCode对应的键盘布局。但是不建议这样做 :)

替代方案:

一个解决方法是使用一个隐藏的(或至少离散的)文本输入框,在应用程序上设置焦点。

当应用程序检测到按键/按下等事件时,可以获取用户输入的值并在画布上呈现它。

由于您已经捕获了键盘事件,处理组合键应该很容易(如果需要的话)。甚至有些情况下这都不是必需的,因为您只需要监视用户输入的长度(您的应用程序不必关心用户是否需要三个按键组合才能输入字符,您只需获取结果即可)。


1
我有作为选项的键盘布局,允许用户覆盖我所做的“最佳猜测”。只要指定了正确的键盘布局,我就不太在意这个问题,只要应用程序执行正确的操作即可。至于在keyPress事件中捕获charCode,我将把它保存为最后的选择。我已经有了这样一个替代文本区域,以使移动设备上的软键盘弹出。但我的想法是,全面、正确的支持将创建一个更强大的应用程序。这将是实现类似Emacs或Vi的强大键盘快捷方式系统所必需的同一基本框架。 - moron4hire
我认为这是一个不错的选择 - 只要您为他们的键盘布局提供映射,它就应该是一个可靠的解决方案。 - Michael

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接