【问题标题】:Translate Javascript keyCode into charCode for non-U.S. keyboard layout (i.e. azerty)将 Javascript keyCode 转换为 charCode 以用于非美国键盘布局(即 azerty)
【发布时间】:2011-06-21 00:58:25
【问题描述】:

快速背景:

  • 当在浏览器中按下某个键时,会生成三个事件:keyDownkeyPresskeyUp
  • keyDownkeyUp 有一个 keyCode 属性,它近似于按下的物理键。
  • keyPress 还具有 charCode 属性集,该属性集考虑了修饰键和键盘布局(A 和 a 具有相同的 keyCode 但不同的 charCode)。
  • 所有三个事件都具有指示在这些事件期间按下了哪些修改键的属性。

我是 noVNC 的主要开发者,我有一个棘手的问题:noVNC 需要翻译后的 charCode 值而不使用 keyPress 事件,原因如下:

  • noVNC 需要将 keyDown 和 keyUp 事件分别发送到 VNC 服务器(否则它不是一个功能齐全的 VNC 客户端)。
  • 更重要的是,noVNC 需要在连接时阻止默认键盘操作,这意味着调用 keyDown 事件的 preventDefault() 方法。这也有防止 keyPress 事件触发的副作用。

由于键盘布局的差异(即不同的 keyCode 到 charCode 映射),我确定 noVNC 需要针对不同键盘布局的查找表。

但真正的问题是:在替代布局中,一些不同的物理键具有 SAME 键码。例如,对于 azerty(法语)键盘布局,“-”(破折号)和“_”下划线键都会生成 keyCode 189。Ack!!!

那么...如何获得正确的 keyCode 到 charCode 映射并同时防止默认浏览器操作?

顺便说一句,我怀疑此解决方案将适用于其他交互式 Web 应用程序和 HTML5 游戏,因为您通常希望能够在不触发任何其他浏览器对该按键的响应的情况下了解有关按键的完整信息。

有用的链接:

解决方案:见下面我的帖子。

【问题讨论】:

    标签: javascript html browser cross-browser


    【解决方案1】:

    我已经解决了我自己的问题。这不是一个 100% 的解决方案,但它应该涵盖大部分需要的内容。希望当浏览器供应商开始集成 DOM Level 3 Events 时会有一个更简洁的解决方案。

    只是为了重申主要约束:

    1. 按键按下和按键按下事件应在实际发生时报告/发送。 IE。在 keyPress 事件期间同时发送一个向下键和向上键是不够的。
    2. 在 keyDown 事件期间必须完全处理许多组合键,因为它们永远不会触发 keyPress 事件(即 Ctrl 键),或者因为必须在 keyDown (WebKit) 中停止默认操作,这样做会阻止 keyPress 事件发生。
    3. 按键按下和按键事件应该报告翻译后的字符代码,而不是 keyCode 值。

    如果没有一些开箱即用的顿悟,当前的浏览器实现似乎无法完全满足所有三个约束。所以我决定稍微放松一下约束 #3。

    • 在浏览器 keyDown 事件中将事件添加到按键列表并检查它是否是安全的(没有不良浏览器默认行为)组合键:

      • 安全:在按键之前什么都不做。

      • 不安全:立即报告/发送按键按下事件。这就是放宽约束 #3 的地方,因为这些有限的组合键没有被转换为字符代码(尽管它们中的许多都没有它们)。

    • 在浏览器 keyPress 事件(在 keyDown 事件之后立即发生)检查它是否是一个安全的组合键:

      • 安全:报告/发送按键按下事件。使用翻译的字符代码 (event.which) 更新按键列表。

      • 不安全:什么都不做,因为它已经在 keyDown 期间报告/发送。

    • 在浏览器keyUp事件中,从按键列表中查找并移除匹配的事件,并使用翻译后的代码上报/发送按键事件。

    一些有趣的附加链接:

    【讨论】:

      【解决方案2】:

      这是一个绝对的雷区,如果可以避免的话,我会敦促你不要尝试这样做。浏览器制造商不仅在关键事件行为上存在着长期而纠结的历史,而且他们仍然不同意并且仍在定期更改浏览器的关键行为。

      以下是我能提供的最好的和关于浏览器关键事件的权威资源:http://unixpapa.com/js/key.html

      如果您必须这样做,我认为您最终会得到大量的键码映射表,这些表很快就会过时。祝你好运。

      【讨论】:

      • 好吧,因为另一个选项更糟糕,我坚持使用键盘布局映射(除非有人能想出一个开箱即用的解决方案)。但是键盘布局映射不是我要问的问题(我可以在某种程度上自动创建映射表),问题是某些布局具有显然无法映射的键。这就是我要问的。我会将您的 unixpapa 链接添加到问题中。
      • 此外,关键事件的另一个缓解因素是 noVNC 仅支持支持 Canvas 的浏览器(因此不支持 IE8 或更低版本),从而减少了一些疯狂。较新的浏览器有所收敛。
      • 另外,关于“抑制默认操作”的 unixpapa 部分。在 Chrome (9) 中,您必须取消 keyDown 才能完全取消默认操作。在 keyPress 中抑制它不起作用。
      • @kanaka:我没有更多建议了。如果两个键具有相同的 keyCode 并且您必须使用 keydown 事件而不是 keypress 事件(您的情况似乎就是这种情况),那么在当前浏览器中没有什么可以做的。
      猜你喜欢
      • 1970-01-01
      • 2012-11-19
      • 2021-11-14
      • 1970-01-01
      • 1970-01-01
      • 2020-07-29
      • 1970-01-01
      • 1970-01-01
      • 2011-01-12
      相关资源
      最近更新 更多