Захват ключей с помощью API блокировки клавиатуры

Обеспечьте захватывающий полноэкранный режим для различных вариантов использования, включая интерактивные веб-сайты, игры, а также потоковую передачу удаленного рабочего стола или приложений.

Поскольку все больше и больше пользователей проводят большую часть своего времени в браузере, интерактивные веб-сайты, игры, потоковая передача с удаленного рабочего стола и потоковая передача приложений стремятся обеспечить захватывающий полноэкранный режим. Для этого сайтам необходим доступ к специальным клавишам и сочетаниям клавиш в полноэкранном режиме, чтобы их можно было использовать для навигации, меню или игр. Некоторые примеры клавиш, которые могут потребоваться: Esc , Alt + Tab , Cmd + ` и Ctrl + N .

По умолчанию эти ключи недоступны веб-приложению, поскольку они фиксируются браузером или базовой операционной системой. API блокировки клавиатуры позволяет веб-сайтам использовать все доступные клавиши, разрешенные операционной системой хоста (см. Совместимость браузера ).

Ubuntu Linux транслируется на вкладку браузера в macOS Chrome (пока не работает в полноэкранном режиме).
Проблема: удаленный рабочий стол Ubuntu Linux с потоковой передачей не работает в полноэкранном режиме и без активной блокировки клавиатуры, поэтому системные клавиши по-прежнему захватываются операционной системой хоста macOS, и процесс еще не является захватывающим.

Использование API блокировки клавиатуры

Интерфейс Keyboard API клавиатуры предоставляет функции, которые переключают захват нажатий клавиш с физической клавиатуры, а также получают информацию о раскладке клавиатуры пользователя.

Предварительное условие

В современных браузерах доступно два типа полноэкранного режима: инициируемый JavaScript через полноэкранный API и инициируемый пользователем с помощью сочетания клавиш. API блокировки клавиатуры доступен только в том случае, если активен полноэкранный режим, инициируемый JavaScript . Вот пример полноэкранного режима, инициируемого JavaScript:

await document.documentElement.requestFullscreen();

Обнаружение функций

Вы можете использовать следующий шаблон, чтобы проверить, поддерживается ли API блокировки клавиатуры:

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

Блокировка клавиатуры

Метод lock() интерфейса Keyboard возвращает обещание после включения захвата нажатий клавиш для любой или всех клавиш на физической клавиатуре. Этот метод может захватывать только те ключи, к которым предоставлен доступ базовой операционной системой. Метод lock() принимает для блокировки массив из одного или нескольких кодов клавиш. Если коды ключей не указаны, все ключи будут заблокированы. Список допустимых значений кодов клавиш доступен в спецификации значений кода KeyboardEvent событий пользовательского интерфейса .

Захват всех ключей

В следующем примере фиксируются все нажатия клавиш.

navigator.keyboard.lock();

Захват определенных ключей

В следующем примере показаны клавиши W , A , S и D. Он фиксирует эти клавиши независимо от того, какие модификаторы используются при нажатии клавиш. Предполагая раскладку US 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() .

Демо

Вы можете протестировать API блокировки клавиатуры, запустив демо-версию на Glitch. Обязательно ознакомьтесь с исходным кодом . Нажатие кнопки «Войти в полноэкранный режим» ниже запускает демо-версию в новом окне, чтобы она могла перейти в полноэкранный режим.

Вопросы безопасности

Одна из проблем, связанных с этим API, заключается в том, что его можно использовать для захвата всех ключей и (в сочетании с полноэкранным API и API PointerLock ) не дать пользователю покинуть веб-страницу. Чтобы предотвратить это, спецификация требует, чтобы браузер предоставил пользователю возможность выйти из блокировки клавиатуры, даже если API запрашивает все клавиши. В Chrome этот аварийный люк представляет собой длительное (две секунды) нажатие клавиши Esc , вызывающее выход из блокировки клавиатуры.

Благодарности

Эта статья была рецензирована Джо Медли и Кейси Баскс . Спецификация Keyboard Lock создана Гэри Качмарчиком и Джейми Уолчем . Изображение героя Кена Суареса на Unsplash .