javascript 2.4.3 Клавиатура: keydown и keyup

Прежде чем перейти к клавиатуре, обратите внимание, что на современных устройствах есть и другие способы «ввести что-то». Например, распознавание речи (это особенно актуально на мобильных устройствах) или Копировать/Вставить с помощью мыши.

Поэтому, если мы хотим корректно отслеживать ввод в поле <input>, то одних клавиатурных событий недостаточно. Существует специальное событие input, чтобы отслеживать любые изменения в поле <input>. И оно справляется с такой задачей намного лучше. Мы рассмотрим его позже в главе События: change, input, cut, copy, paste.

События клавиатуры же должны использоваться, если мы хотим обрабатывать взаимодействие пользователя именно с клавиатурой (в том числе виртуальной). К примеру, если нам нужно реагировать на стрелочные клавиши Up и Down или горячие клавиши (включая комбинации клавиш).

События keydown и keyup

Событие keydown происходит при нажатии клавиши, а keyup – при отпускании.

event.code и event.key

Свойство key объекта события позволяет получить символ, а свойство code – «физический код клавиши».

К примеру, одну и ту же клавишу Z можно нажать с клавишей Shift и без неё. В результате получится два разных символа: z в нижнем регистре и Z в верхнем регистре.

Свойство event.key – это непосредственно символ, и он может различаться. Но event.code всегда будет тот же:

Клавишаevent.keyevent.code
Zz (нижний регистр)KeyZ
Shift+ZZ (Верхний регистр)KeyZ

Если пользователь работает с разными языками, то при переключении на другой язык символ изменится с "Z" на совершенно другой. Получившееся станет новым значением event.key, тогда как event.code останется тем же: "KeyZ".«KeyZ» и другие клавишные коды

У каждой клавиши есть код, который зависит от её расположения на клавиатуре. Подробно о клавишных кодах можно прочитать в спецификации о кодах событий UI.

Например:

  • Буквенные клавиши имеют коды по типу "Key<буква>""KeyA""KeyB" и т.д.
  • Коды числовых клавиш строятся по принципу: "Digit<число>""Digit0""Digit1" и т.д.
  • Код специальных клавиш – это их имя: "Enter""Backspace""Tab" и т.д.

Существует несколько широко распространённых раскладок клавиатуры, и в спецификации приведены клавишные коды к каждой из них.

Можно их прочитать в разделе спецификации, посвящённом буквенно-цифровым клавишам или просто нажмите нужную клавишу на тестовом стенде выше и посмотрите.Регистр важен: "KeyZ", а не "keyZ"

Выглядит очевидно, но многие всё равно ошибаются.

Пожалуйста, избегайте опечаток: правильно KeyZ, а не keyZ. Условие event.code=="keyZ" работать не будет: первая буква в слове "Key" должна быть заглавная.

А что, если клавиша не буквенно-цифровая? Например, Shift или F1, или какая-либо другая специальная клавиша? В таких случаях значение свойства event.key примерно тоже, что и у event.code:

Клавишаevent.keyevent.code
F1F1F1
BackspaceBackspaceBackspace
ShiftShiftShiftRight или ShiftLeft

Обратите внимание, что event.code точно указывает, какая именно клавиша нажата. Так, большинство клавиатур имеют по две клавиши Shift: слева и справа. event.code уточняет, какая именно из них была нажата, в то время как event.key сообщает о «смысле» клавиши: что вообще было нажато (Shift).

Допустим, мы хотим обработать горячую клавишу Ctrl+Z (или Cmd+Z для Mac). Большинство текстовых редакторов к этой комбинации подключают действие «Отменить». Мы можем поставить обработчик событий на keydown и проверять, какая клавиша была нажата.

Здесь возникает дилемма: в нашем обработчике стоит проверять значение event.key или event.code?

С одной стороны, значение event.key – это символ, он изменяется в зависимости от языка, и если у пользователя установлено в ОС несколько языков, и он переключается между ними, нажатие на одну и ту же клавишу будет давать разные символы. Так что имеет смысл проверять event.code, ведь его значение всегда одно и тоже.

Вот пример кода:

document.addEventListener('keydown', function(event) {
  if (event.code == 'KeyZ' && (event.ctrlKey || event.metaKey)) {
    alert('Отменить!')
  }
});

С другой стороны, с event.code тоже есть проблемы. На разных раскладках к одной и той же клавише могут быть привязаны разные символы.

Например, вот схема стандартной (US) раскладки («QWERTY») и под ней немецкой («QWERTZ») раскладки (из Википедии):

Для одной и той же клавиши в американской раскладке значение event.code равно «Z», в то время как в немецкой «Y».

Буквально, для пользователей с немецкой раскладкой event.code при нажатии на Y будет равен KeyZ.

Если мы будем проверять в нашем коде event.code == 'KeyZ', то для людей с немецкой раскладкой такая проверка сработает, когда они нажимают Y.

Звучит очень странно, но это и в самом деле так. В спецификации прямо упоминается такое поведение.

Так что event.code может содержать неправильный символ при неожиданной раскладке. Одни и те же буквы на разных раскладках могут сопоставляться с разными физическими клавишами, что приводит к разным кодам. К счастью, это происходит не со всеми кодами, а с несколькими, например KeyAKeyQKeyZ (как мы уже видели), и не происходит со специальными клавишами, такими как Shift. Вы можете найти полный список проблемных кодов в спецификации.

Чтобы отслеживать символы, зависящие от раскладки, event.key надёжнее.

С другой стороны, преимущество event.code заключается в том, что его значение всегда остаётся неизменным, будучи привязанным к физическому местоположению клавиши, даже если пользователь меняет язык. Так что горячие клавиши, использующие это свойство, будут работать даже в случае переключения языка.

Хотим поддерживать клавиши, меняющиеся при раскладке? Тогда event.key – верный выбор.

Или мы хотим, чтобы горячая клавиша срабатывала даже после переключения на другой язык? Тогда event.code может быть лучше.

Запись опубликована в рубрике javascript. Добавьте в закладки постоянную ссылку.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *