KeyboardEvent.keyCode устарел. Что это значит на практике?

103

Согласно MDN, мы определенно не должны использовать это .keyCodeсвойство. Устарело:

https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode

В школе W3 этот факт преуменьшается, и есть только примечание сбоку, в котором говорится, что .keyCodeоно предоставляется только для совместимости и что последняя версия спецификации событий DOM рекомендует использовать .keyвместо этого свойство.

Проблема в том, что .keyэто не поддерживается браузерами, так что же нам использовать? Что-то мне не хватает?

Джейсон210
источник
3
.keyподдерживается во всех основных браузерах developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/…
Синан Болел,

Ответы:

37

У вас есть три способа справиться с этим, как написано в ссылке, которой вы поделились.

if (event.key !== undefined) {

} else if (event.keyIdentifier !== undefined) {

} else if (event.keyCode !== undefined) {

}

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

Было бы проще, если бы вы реализовали что-то вроде этого.

var dispatchForCode = function(event, callback) {
  var code;

  if (event.key !== undefined) {
    code = event.key;
  } else if (event.keyIdentifier !== undefined) {
    code = event.keyIdentifier;
  } else if (event.keyCode !== undefined) {
    code = event.keyCode;
  }

  callback(code);
};
Мигель Латтуада
источник
15
Я действительно читал это, но, похоже, это было много дополнительного кода только по той причине, что MDN сказал, что что-то устарело, хотя на самом деле оно отлично работает во всех основных браузерах. Но если это правильный способ, то спасибо!
Jason210,
3
Ух ты посмотри на это. caniuse.com/#search=keyCode (Это свойство KeyboardEvent поддерживается практически во всех браузерах (начиная с IE6 +, Firefox 2+, Chrome 1+ и т. д., говоря о .keyCode)
Мигель Латтуада,
2
Вот что во всем этом так раздражает. Все основные браузеры поддерживают keyCode, но попробуйте проверить свойство .key, которое является рекомендуемым, и вряд ли кто-нибудь его использует!
Jason210
4
Да, мы подошли к концу мая 2016 года, и в Chrome наконец-то реализовано свойство KeyboardEvent.key. Safari, как и все мобильные браузеры, еще не присоединился к партии «16,5% всех пользователей». К сожалению, Microsoft Edge и Gecko по-разному кодируют довольно много событий, например: ключевое событие для стрелки вверх кодируется как «Вверх» вместо «ArrowUp».
Джошуа Доусон
Думаю, это поможет вам stackoverflow.com/questions/41465542/…
Maven97
26

Кроме того, все keyCode , которые , charCode и keyIdentifier устарели:
charCodeи keyIdentifierявляются нестандартными функциями.
keyIdentifierудаляется с Chrome 54, а Opera 41.0
keyCodeвозвращает 0 при нажатии клавиши с обычными символами на FF.

Ключевое свойство :

 readonly attribute DOMString key

Содержит значение ключевого атрибута, соответствующее нажатой клавише

На момент написания этой статьи keyсвойство поддерживается всеми основными браузерами, начиная с: Firefox 52, Chrome 55, Safari 10.1, Opera 46. За исключением Internet Explorer 11, который имеет: нестандартные идентификаторы ключей и неправильное поведение с AltGraph. Дополнительная информация
Если это важно и / или имеет обратную совместимость, вы можете использовать обнаружение функций, как в следующем коде:

Обратите внимание, что keyзначение отличается от keyCodeили whichсвойств в этом: оно содержит имя ключа, а не его код. Если вашей программе нужны коды символов, вы можете использовать charCodeAt(). Для одиночных печатных символов вы можете использовать charCodeAt(), если вы имеете дело с ключами, значения которых содержат несколько символов, например, ArrowUp вероятность: вы проверяете специальные ключи и принимаете соответствующие меры. Так попробовать реализовать таблицу значений " ключи и соответствующие им коды charCodeArr["ArrowUp"]=38, charCodeArr["Enter"]=13, charCodeArr[Escape]=27... и так далее, пожалуйста , обратите внимание на ключевые ценности и их соответствующих кодов

if(e.key!=undefined){
        var characterCode = charCodeArr[e.key] || e.key.charCodeAt(0);
    }else{
        /* As @Leonid suggeted   */
        var characterCode = e.which || e.charCode || e.keyCode || 0;
    }
        /* ... code making use of characterCode variable  */  

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

if(e.which || e.charCode || e.keyCode ){
        var characterCode = e.which || e.charCode || e.keyCode;
    }else if (e.key!=undefined){
        var characterCode = charCodeArr[e.key] || e.key.charCodeAt(0);
    }else{
        var characterCode = 0;
    }

См. Также: документацию по KeyboardEvent.codeсвойствам и некоторые дополнительные сведения в этом ответе .

user10089632
источник
Ваше решение не работает в моем браузере (Windows 10, Chrome 60, бельгийская клавиатура). Во-первых, charCodeArrфункции не существует. Кроме того, charCodeAtне работает для всех значений e.key. Например, для ключа Enter/ Returnзначение e.keyсвойства равно "Enter", и выполнение charCodeArrдля этой строки возвращает значение 69(которое является кодом ASCII для символа E).
Джон
@JohnSlegers, да, это была опечатка, я имел в виду массив, созданный пользователем. Пожалуйста, смотрите мой обновленный ответ для более подробной информации.
user10089632
22

TLDR: Я хотел бы предложить , что вы должны использовать новый event.keyи event.codeсвойство вместо устаревших единиц. IE и Edge поддерживают эти свойства, но пока не поддерживают новые имена ключей. Для них есть небольшой полифилл, который заставляет их выводить стандартные имена ключей / кодов:

https://github.com/shvaikalesh/shim-keyboard-event-key


Я пришел к этому вопросу в поисках причины того же предупреждения MDN, что и OP. После еще нескольких поисков проблема с keyCodeстановится более ясной:

Проблема с использованием keyCodeнеанглийских клавиатур может давать разные результаты, и даже клавиатуры с разной раскладкой могут давать противоречивые результаты. Плюс был случай

Если вы читали спецификацию W3C: https://www.w3.org/TR/uievents/#interface-keyboardevent

На практике keyCode и charCode несовместимы на разных платформах и даже имеют одинаковую реализацию в разных операционных системах или с использованием разных локализаций.

Здесь подробно описывается, что было не так keyCode: https://www.w3.org/TR/uievents/#legacy-key-attributes

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

Итак, установив причину замены устаревшего keyCode, давайте посмотрим, что вам нужно сделать сегодня:

  1. Все современные браузеры поддерживают новые свойства ( keyи code).
  2. IE и Edge поддерживают старую версию спецификации, у которой разные имена для некоторых ключей. Вы можете использовать для этого прокладку: https://github.com/shvaikalesh/shim-keyboard-event-key (или сверните свой собственный - в любом случае он довольно маленький)
  3. Edge исправил эту ошибку в последней версии (вероятно, будет выпущен в апреле 2018 г.) - https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/8860571/
  4. См. Список ключей событий, которые вы можете использовать: https://www.w3.org/TR/uievents-key/
кумархарш
источник
Согласно MDN , ни Internet Explorer, ни Edge не поддерживаютKeyboardEvent.code. Кроме того, значенияkeyиcodeзависят от браузера. Обе проблемы создаютkeyиcodeне подходят для использования в реальных приложениях.
Джон Слегерс
@JohnSlegers пожалуйста , см developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key
kumarharsh
Если я хочу протестировать клавиши со стрелками, страницы вверх / вниз, домой и конец, я должен использовать keyили code? Обычно это физическая клавиша, но это может зависеть также от Num Lock и раскладки ... Какая наилучшая практика?
Джейк
15

MDN уже предоставил решение:

https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode

window.addEventListener("keydown", function (event) {
  if (event.defaultPrevented) {
    return; // Should do nothing if the default action has been cancelled
  }

  var handled = false;
  if (event.key !== undefined) {
    // Handle the event with KeyboardEvent.key and set handled true.
  } else if (event.keyIdentifier !== undefined) {
    // Handle the event with KeyboardEvent.keyIdentifier and set handled true.
  } else if (event.keyCode !== undefined) {
    // Handle the event with KeyboardEvent.keyCode and set handled true.
  }

  if (handled) {
    // Suppress "double action" if event handled
    event.preventDefault();
  }
}, true);
Вики Гонсалвес
источник
3
К сожалению, keyэто строковое значение, зависящее от браузера, например "Enter"или, "ArrowUp"и не существует стандартизированного способа его преобразования в соответствующий код. так что вам понадобится еще больше шаблонного кода для преобразования между ключом и кодом.
Джон
8

Например, если вы хотите определить, была ли нажата клавиша «Enter» или нет:

Вместо того

event.keyCode === 13

Сделай это как

event.key === 'Enter'
Томас Готвиг
источник