使用 Keyboard Lock API 擷取金鑰

為各種用途提供沉浸式全螢幕體驗,包括互動式網站、遊戲,以及遠端桌面或應用程式串流。

越來越多使用者的大部分時間都花在瀏覽器上,因此互動豐富的網站、遊戲、遠端桌面串流和應用程式串流,都致力於提供沉浸式全螢幕體驗。為此,網站必須在全螢幕模式下存取特殊鍵和鍵盤快速鍵,才能用於導覽、選單或遊戲。可能需要按下的按鍵包括 EscAlt + TabCmd + `Ctrl + N

根據預設,這些按鍵會由瀏覽器或基礎作業系統擷取,因此網頁應用程式無法使用。網站可透過鍵盤鎖定 API 使用主機 OS 允許的所有可用鍵 (請參閱瀏覽器相容性)。

Ubuntu Linux 串流至 macOS Chrome 的瀏覽器分頁 (尚未以全螢幕模式執行)。
問題:串流的 Ubuntu Linux 遠端桌面以全螢幕模式執行,且啟用鍵盤鎖定, 因此 macOS 主機作業系統仍會擷取系統鍵,且體驗夠沉浸。

使用 Keyboard Lock API

Keyboard API 的 Keyboard 介面提供多項函式,可切換擷取實體鍵盤的按鍵動作,以及取得使用者鍵盤配置的相關資訊。

修課條件

新式瀏覽器提供兩種全螢幕模式:透過 Fullscreen API 以 JavaScript 啟動,以及透過鍵盤快速鍵由使用者啟動。只有在 JavaScript 啟動的全螢幕模式處於啟用狀態時,才能使用鍵盤鎖定 API。 以下是 JavaScript 啟動全螢幕的範例:

await document.documentElement.requestFullscreen();

特徵偵測

您可以使用下列模式,檢查是否支援 Keyboard Lock API:

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

鎖定鍵盤

啟用擷取實體鍵盤上任何或所有按鍵的按鍵按下事件後,Keyboard 介面的 lock() 方法會傳回 Promise。這個方法只能擷取基礎作業系統授予存取權的金鑰。lock() 方法會採用一或多個要鎖定的鍵碼陣列。如果未提供任何解鎖代碼,所有鑰匙都會鎖上。如需有效鍵碼值的清單,請參閱 UI Events KeyboardEvent code Values 規格。

擷取所有按鍵

以下範例會擷取所有按鍵。

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()

示範

您可以執行這項示範,測試鍵盤鎖定 API。請務必查看原始碼。按一下下方的「Enter full screen」(進入全螢幕模式) 按鈕,即可在新視窗中啟動示範,並進入全螢幕模式。

安全考量

這個 API 的一個問題是,它可用來擷取所有按鍵,並 (搭配 Fullscreen APIPointerLock API) 阻止使用者離開網頁。為避免這種情況,規格要求瀏覽器提供方法,讓使用者即使在 API 要求所有按鍵的情況下,也能退出鍵盤鎖定模式。在 Chrome 中,只要長按 (兩秒) Esc 鍵,即可觸發鍵盤鎖定模式的退出機制。

特別銘謝

本文由 Joe MedleyKayce Basques 審查。鍵盤鎖定規格是由 Gary KacmarcikJamie Walch 撰寫。主頁橫幅圖片由 Ken SuarezUnsplash 上提供。