使用 Keyboard Lock API 捕获按键

为各种应用场景(包括互动式网站、游戏、远程桌面或应用流式传输)提供沉浸式全屏体验。

随着越来越多的用户将大部分时间花在浏览器上,互动性丰富的网站、游戏、远程桌面流式传输和应用流式传输都在努力提供沉浸式全屏体验。为此,网站需要在全屏模式下访问特殊按键和键盘快捷键,以便将其用于导航、菜单或游戏。可能需要使用的按键包括 Esc、Alt + Tab、Cmd + ` 和 Ctrl + N。

默认情况下,这些按键无法供 Web 应用使用,因为它们会被浏览器或底层操作系统捕获。Keyboard Lock API 使网站能够使用主机操作系统允许的所有可用按键(请参阅浏览器兼容性)。

Ubuntu Linux 流式传输到 macOS Chrome 中的浏览器标签页(尚未在全屏模式下运行)。
问题:流式传输的 Ubuntu Linux 远程桌面未以全屏模式运行,并且未启用键盘锁定,因此系统键仍由 macOS 主机操作系统捕获,体验不够沉浸。

使用 Keyboard Lock API

Keyboard API 的 Keyboard 接口提供了一些函数,用于切换是否捕获实体键盘上的按键操作,以及获取有关用户键盘布局的信息。

前提条件

现代浏览器支持两种全屏模式:通过 Fullscreen API 由 JavaScript 启动的全屏模式,以及通过键盘快捷键由用户启动的全屏模式。Keyboard Lock API 仅在由 JavaScript 启动的全屏模式处于启用状态时可用。 以下是 JavaScript 启动的全屏示例:

await document.documentElement.requestFullscreen();

功能检测

您可以使用以下模式检查是否支持 Keyboard Lock API:

if ('keyboard' in navigator && 'lock' in navigator.keyboard) {
  // Supported!
}

锁定键盘

Keyboard 接口的 lock() 方法会在启用对实体键盘上任何或所有按键的按压捕获后返回一个 promise。此方法只能捕获底层操作系统授予访问权限的按键。lock() 方法接受一个或多个要锁定的按键代码组成的数组。如果未提供按键代码,则所有按键都将被锁定。界面事件 KeyboardEvent 代码值规范中提供了有效键代码值的列表。

正在捕获所有按键

以下示例会捕获所有按键操作。

navigator.keyboard.lock();

捕获特定按键

以下示例会捕获 W、A、S 和 D 键。无论按键时使用哪些辅助键,它都会捕获这些按键。假设采用美国 QWERTY 布局,注册 "KeyW" 可确保 W、Shift + W、Control + W、Control + Shift + W 以及与 W 组合的所有其他辅助键组合都会发送到应用。"KeyA"、"KeyS" 和 "KeyD" 也是如此。

await navigator.keyboard.lock([
  "KeyW",
  "KeyA",
  "KeyS",
  "KeyD",
]);

您可以使用键盘事件来响应捕获的按键操作。 例如,以下代码使用了 onkeydown 事件:

document.addEventListener('keydown', (event) => {
  if ((event.code === 'KeyA') && !(event.ctrlKey || event.metaKey)) {
    // Do something when the 'A' key was pressed, but only
    // when not in combination with the command or control key.
  }
});

解锁键盘

unlock() 方法会解锁 lock() 方法捕获的所有键,并同步返回。

navigator.keyboard.unlock();

当文档关闭时,浏览器始终会隐式调用 unlock()。

演示

您可以通过运行此演示来测试 Keyboard Lock API。请务必查看源代码。点击下方的“进入全屏”按钮,即可在新窗口中启动演示,以便进入全屏模式。

安全注意事项

此 API 的一个问题是,它可用于捕获所有按键,并(与 Fullscreen API 和 PointerLock API 结合使用)阻止用户退出网页。为了防止这种情况,规范要求浏览器为用户提供一种退出键盘锁定的方法,即使 API 请求了所有按键也是如此。在 Chrome 中,此应急机制是长按(两秒)Esc 键,以触发退出键盘锁定。

致谢

本文由 Joe Medley 和 Kayce Basques 审核。Keyboard Lock 规范由 Gary Kacmarcik 和 Jamie Walch 编写。