Информация о Keycode

Нажмите клавишу и прочитайте каждое свойство полученного KeyboardEvent: key, code, keyCode, which, location и флаги ctrl, shift, alt и meta, а также копируемый JSON.

Нажмите клавишу. Увидьте точно то, что сообщает браузер. Нажмите область захвата ниже и нажмите любую клавишу или комбинацию. Каждое свойство KeyboardEvent показано бок о бок, чтобы вы могли выбрать правильное для своего обработчика сочетаний клавиш, а не угадывать.

event.key
event.code
event.keyCode
event.which
event.location
Удерживаемые модификаторы
нет

key, code и keyCode - это не одно и то же

Три свойства, три разных вопроса

KeyboardEvent предоставляет несколько способов идентифицировать клавишу, и они отвечают на действительно разные вопросы. event.key - это символ или именованное значение, получаемое нажатием после применения раскладки и модификаторов. Нажатие физической клавиши A даёт a, или A при удержании shift, или вообще другую букву на раскладке Dvorak или AZERTY. Именованные клавиши приходят как описательные строки, такие как Enter, Escape, ArrowLeft и F5.

event.code идентифицирует физическую позицию клавиши, используя не зависящее от раскладки имя, взятое из условной американской клавиатуры. Клавиша на позиции A всегда KeyA, независимо от того, что выдаёт раскладка пользователя. Цифры в верхнем ряду - это Digit1 по Digit0, а цифровая клавиатура сообщает Numpad1 и компания, чтобы вы могли отличить два ряда цифр.

event.keyCode и его двойник event.which - это устаревшие числовые идентификаторы. Оба официально устарели, оба всё ещё реализованы везде и оба непоследовательны между браузерами для пунктуации. Их стоит читать при сопровождении старого кода, но новая обработка сочетаний клавиш должна использовать key или code.

Выбор между key и code

Правило большого пальца простое: используйте code, когда важна позиция, и key, когда важен смысл. Игра, привязывающая передвижение к WASD, хочет code, потому что физический кластер под левой рукой игрока должен оставаться на месте на клавиатуре AZERTY, даже если он выдаёт ZQSD. Текстовый редактор, привязывающий «сохранить» к Ctrl+S, хочет key, потому что пользователь мыслит буквой S, а не клавишей рядом с A.

Флаги модификаторов - это отдельные логические значения: ctrlKey, shiftKey, altKey и metaKey. Проверяйте их явно, а не выводите из key, и помните, что основной модификатор сочетания - Command на macOS и Control в остальных системах. Распространённый шаблон - принимать event.metaKey || event.ctrlKey, чтобы один обработчик покрывал обе платформы.

event.location различает продублированные клавиши. Это 0 для обычной клавиши, 1 для левого члена пары, такой как левый Shift, 2 для правого и 3 для клавиши на цифровой клавиатуре.

Практические подводные камни

Не каждая клавиша генерирует ожидаемые события. Браузер резервирует некоторые комбинации для себя - Ctrl+W, Ctrl+T и Command+Q обычно закрывают вкладки или завершают приложение раньше, чем страница их увидит, и preventDefault не может их вернуть. Проверяйте любое сочетание в реальном окне браузера, а не предполагайте, что оно дойдёт до вашего обработчика.

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

Наконец, keydown и keyup описывают клавиши, а keypress описывал символы и был удалён из стандарта. Для текстового ввода лучше слушать событие input или читать beforeinput, которые гораздо надёжнее обрабатывают композицию, автозаполнение и мобильные клавиатуры, чем любое событие уровня клавиш.

Примечание об открытом ПО: реализовано на чистом JavaScript без сторонних библиотек.

Часто задаваемые вопросы

Использовать key или code для сочетания клавиш?
Используйте `code`, когда важна физическая позиция, например передвижение WASD в игре. Используйте `key`, когда важен смысл, например Ctrl+S для сохранения, чтобы сочетание следовало за вашей собственной раскладкой.
Почему keyCode устарел, но всё ещё работает?
Он предшествует событиям, учитывающим раскладку, и возвращает непоследовательные числа для пунктуации в разных браузерах. Каждый движок всё ещё реализует его для совместимости, но спецификация направляет новый код к `key` и `code`.
Ничего не происходит, когда я нажимаю Ctrl+W или Command+Q.
Эти комбинации захватываются браузером или операционной системой и обрабатываются раньше, чем страница их получает. Надёжного способа перехватить их из обычной веб-страницы нет.
Как написать одно сочетание, работающее на macOS и Windows?
Принимайте любой основной модификатор, проверяя `event.metaKey || event.ctrlKey`. Это отображается на Command в macOS и Control в Windows и Linux без ветвления по user-agent.
Что означает location 3?
Клавиша находится на цифровой клавиатуре. Location 1 и 2 означают левый и правый член продублированной пары, такой как Shift или Control, а 0 - обычную клавишу без дубликата.
Можно ли использовать это для обработчика текстового ввода?
Лучше слушать событие `input`. События клавиш пропускают композицию из IME-клавиатур, автозаполнение и многие мобильные виртуальные клавиатуры, всё это `input` сообщает корректно.