KeyboardEvent.keyCode застарілий. Що це означає на практиці?


101

Відповідно до MDN, ми точно не повинні використовувати.keyCode властивість. Це застаріло:

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

У школі W3 цей факт проігноровано, і є лише допоміжна примітка, яка .keyCodeпередбачає лише сумісність, і що остання версія Специфікації подій DOM рекомендує використовувати .keyвластивість замість цього.

Проблема в тому, що .keyбраузери не підтримують, то що ми повинні використовувати? Щось мені не вистачає?


3
.keyпідтримується у кожному великому розробнику
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властивості docs та деякі додаткові відомості у цій відповіді .


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

@JohnSlegers, так, це була помилка, я мав на увазі побудований користувачем масив. Будь ласка, див. Мою оновлену відповідь для отримання детальної інформації.
user10089632

21

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"і немає стандартизованого способу перетворити його у відповідний код. так що вам знадобиться ще більше зразкового коду для перетворення між ключем і кодом.
Джон Слегерс,

6

Наприклад, якщо ви хочете визначити, натиснуто клавішу "Enter" чи ні:

Замість

event.keyCode === 13

Робіть це як

event.key === 'Enter'
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.