快速背景:
- 在浏览器中按下键时,会生成三个事件:keyDown、keyPress 和 keyUp。
- keyDown 和 keyUp 有一个 keyCode 属性,该属性大致表示按下的物理键。
- keyPress 还设置了一个 charCode 属性,考虑到修饰键和键盘布局(A 和 a 具有相同的 keyCode,但具有不同的 charCode)。
- 这三个事件都有指示在这些事件期间按下了哪些修改键的属性。
我是主要的 noVNC 开发人员,我面临一个棘手的问题:noVNC 需要翻译后的 charCode 值,而不使用 keyPress 事件,原因如下:
- noVNC 需要将 keyDown 和 keyUp 事件分别发送到 VNC 服务器(否则它不是一个完全功能的 VNC 客户端)。
- 更重要的是,noVNC 需要在连接时防止默认的键盘操作,这意味着调用 keyDown 事件的 preventDefault() 方法。这会导致 keyPress 事件也无法触发。
由于键盘布局的差异(即不同的 keyCode 到 charCode 映射),我已确定 noVNC 需要一个查找表来处理不同的键盘布局。
但是这里真正的问题是:在备选布局中,一些不同的物理键具有相同的keyCode。例如,在azerty(法语)键盘布局中,'-'(破折号)和'_'(下划线)键都会生成keyCode 189.啊!!!
那么...我如何同时获得适当的keyCode到charCode映射并防止默认浏览器操作呢?
顺便说一句,我怀疑这个解决方案适用于其他交互式Web应用程序和HTML5游戏,因为您经常希望能够了解按下的键的完整信息,而不触发任何其他浏览器响应该按键。
有用的链接:
- 这里是一个有用的测试页面,显示了三个事件和其他一些有用的属性。
- Javascript键事件的疯狂状态摘要(感谢@Tim)
- Quirksmode 检测按键
- Quirksmode 事件-键事件
- noVNC问题,更多讨论此问题。
解决方案:请参见下面的我的帖子。