使用 Keyboard Lock API 捕获按键

为各种用例(包括交互式网站、游戏以及远程桌面或应用串流)提供沉浸式全屏体验。

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

默认情况下,这些密钥对 Web 应用不可用,因为浏览器或底层操作系统会捕获这些密钥。借助 Keyboard Lock API,网站可以使用主机操作系统允许的所有可用键(请参阅浏览器兼容性)。

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

使用 Keyboard Lock API

Keyboard API 的 Keyboard 接口提供了一些功能,可切换捕获来自实体键盘的按键操作,以及获取有关用户键盘布局的信息。

前提条件

新型浏览器支持两种全屏:JavaScript 通过 Fullscreen API 启动,用户通过键盘快捷键启动。仅当 JavaScript 发起的全屏处于启用状态时,Keyboard Lock API 才可用。下面是 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();

捕获特定键

以下示例会捕获 WASD 键。无论按键操作使用的是哪个辅助键,它都会捕获这些按键。假设使用的是美式 QWERTY 布局,注册 "KeyW" 可确保向应用发送 WShift + WControl + WControl + 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()

演示

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

安全注意事项

此 API 存在的一个问题是,它可用于获取所有密钥,并且(与 Fullscreen APIPointerLock API 结合使用)会阻止用户退出网页。为防止出现这种情况,该规范要求浏览器为用户提供退出键盘锁定的方式,即使 API 请求所有按键,也是如此。在 Chrome 中,长按 Esc 键(时长为 2 秒)即可触发退出“键盘锁定”功能。

致谢

本文由 Joe MedleyKayce Basques 审核。键盘锁定规范由 Gary KacmarcikJamie Walch 编写。 主打图片:Ken SuarezUnsplash 用户。