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

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

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

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

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

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

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

Предпосылки

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

await document.documentElement.requestFullscreen();

Обнаружение особенностей

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

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

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

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

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

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

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 блокировки клавиатуры, запустив эту демонстрацию . Обязательно ознакомьтесь с исходным кодом . Нажатие кнопки «Перейти в полноэкранный режим» ниже запускает демонстрацию в новом окне, позволяя перейти в полноэкранный режим.

Соображения безопасности

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

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

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