Przechwytywanie klawiszy przy użyciu interfejsu Keyboard Lock API

Zapewnianie wciągających wrażeń na pełnym ekranie w różnych zastosowaniach, w tym w przypadku interaktywnych witryn, gier oraz strumieniowego przesyłania pulpitu zdalnego lub aplikacji.

Coraz więcej użytkowników spędza większość czasu w przeglądarce, a interaktywne strony internetowe, gry, zdalne pulpity i aplikacje strumieniowe starają się zapewnić wrażenia pełnoekranowe. Aby to osiągnąć, strony muszą mieć dostęp do specjalnych klawiszy i skrótów klawiszowych w trybie pełnoekranowym, aby można było ich używać do nawigacji, korzystania z menu czy grania. Przykładowe klawisze, które mogą być wymagane, to Esc, Alt + Tab, Cmd + ` oraz Ctrl + N.

Domyślnie te klucze są niedostępne dla aplikacji internetowej, ponieważ są przechwytywane przez przeglądarkę lub system operacyjny. Interfejs Keyboard Lock API umożliwia witrynom używanie wszystkich kluczy dozwolonych przez system operacyjny hosta (zobacz Zgodność przeglądarki).

Ubuntu Linux przesyłany strumieniowo na kartę przeglądarki w Chrome na macOS (nie działa jeszcze w trybie pełnoekranowym).
Problem: strumień zdalnego pulpitu Ubuntu Linux nie działa w trybie pełnoekranowym i bez aktywnego blokowania klawiatury, więc klawisze systemowe są nadal przechwytywane przez system operacyjny hosta macOS, a funkcja nie jest jeszcze w pełni płynna.

Korzystanie z interfejsu Keyboard Lock API

Interfejs Keyboard interfejsu Keyboard API udostępnia funkcje, które przełączają rejestrowanie naciśnięć klawiszy na fizycznej klawiaturze, a także umożliwiają uzyskiwanie informacji o rozkładzie klawiatury użytkownika.

Warunek wstępny

W nowoczesnych przeglądarkach dostępne są 2 typy pełnego ekranu: inicjowany przez JavaScript za pomocą interfejsu Fullscreen API oraz inicjowany przez użytkownika za pomocą skrótu klawiszowego. Interfejs Keyboard Lock API jest dostępny tylko wtedy, gdy włączony jest pełny ekran inicjowany za pomocą JavaScriptu. Oto przykład pełnego ekranu wywołanego za pomocą kodu JavaScript:

await document.documentElement.requestFullscreen();

Wykrywanie cech

Aby sprawdzić, czy interfejs KeyboardLock API jest obsługiwany, możesz użyć tego wzorca:

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

Blokowanie klawiatury

Metoda lock() interfejsu Keyboard zwraca obietnicę po włączeniu przechwytywania naciśnięć klawiszy dotyczących dowolnego lub wszystkich klawiszy na klawiaturze fizycznej. Ta metoda może przechwytywać tylko klucze, do których dostęp przyznaje bazowy system operacyjny. Metoda lock() przyjmuje tablicę co najmniej 1 klucza. Jeśli nie podasz kodów kluczy, wszystkie klucze zostaną zablokowane. Lista prawidłowych wartości kodu klawisza jest dostępna w specyfikacji UI Events KeyboardEvent code Values (Zdarzenia UI – wartości kodu KeyboardEvent).

Przechwytywanie wszystkich klawiszy

W tym przykładzie rejestrowane są wszystkie naciśnięcia klawiszy.

navigator.keyboard.lock();

Przechwytywanie określonych klawiszy

W tym przykładzie uwzględniono klucze W, A, SD. Rejestruje te klawisze niezależnie od tego, jakie modyfikatory są używane podczas ich naciśnięcia. Przy założeniu, że masz układ QWERTY amerykański, rejestracja "KeyW" powoduje, że W, Shift + W, Control + W, Control + Shift + W oraz wszystkie inne kombinacje klawiszy modyfikujących z W są wysyłane do aplikacji. To samo dotyczy "KeyA", "KeyS""KeyD".

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

Możesz reagować na zarejestrowane naciśnięcia klawiszy za pomocą zdarzeń klawiatury. Ten kod korzysta na przykład ze zdarzenia 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.
  }
});

Odblokowywanie klawiatury

Metoda unlock() odblokowuje wszystkie klucze zarejestrowane przez metodę lock() i zwraca je synchronicznie.

navigator.keyboard.unlock();

Po zamknięciu dokumentu przeglądarka zawsze wywołuje niejawnie funkcję unlock().

Prezentacja

Aby przetestować interfejs Keyboard Lock API, uruchom demo na Glitch. Pamiętaj, aby sprawdzić kod źródłowy. Kliknięcie przycisku Włącz tryb pełnoekranowy poniżej spowoduje uruchomienie wersji demonstracyjnej w nowym oknie, aby można było przejść do trybu pełnoekranowego.

Zagadnienia związane z bezpieczeństwem

Jednym z potencjalnych problemów z tym interfejsem API jest to, że może on służyć do przechwytywania wszystkich klawiszy i (w połączeniu z interfejsem Fullscreen API i interfejsem PointerLock API) uniemożliwiania użytkownikowi opuszczenia strony internetowej. Aby temu zapobiec, specyfikacja wymaga, aby przeglądarka umożliwiała użytkownikowi wyjście z blokady klawiatury, nawet jeśli interfejs API żąda wszystkich kluczy. W Chrome wyjście z blokady klawiatury można wywołać, naciskając przez 2 sekundy klawisz Esc.

Podziękowania

Ten artykuł został sprawdzony przez Joe Medley i Kayce Basques. Specyfikacja blokady klawiatury została przygotowana przez Gary’ego KacmarcikaJamiego Walcha. Baner powitalny autorstwa Ken Suarez z Unsplash.