.keyCode vs. .which


228

Я думав, що на це відповістимуть десь у стеку Overflow, але не можу його знайти.

Якщо я слухаю подію натискання клавіші, чи повинен я використовувати .keyCodeабо .whichвизначити, чи була натиснута клавіша Enter?

Я завжди робив щось подібне:

$("#someid").keypress(function(e) {
  if (e.keyCode === 13) {
    e.preventDefault();
    // do something
  }
});

Але я бачу приклади, які використовують .whichзамість .keyCode. Яка різниця? Чи один із крос-браузерів дружніший, ніж інший?


Відповіді:


209

Примітка . Відповідь, написана нижче, була написана в 2010 році. Тут через багато років обидва keyCodeі whichзастаріли на користь key(для логічного ключа) та code(для фізичного розміщення ключа). Але зауважте, що IE не підтримує code, і його підтримка keyбазується на старій версії специфікації, тому не зовсім коректно. Коли я пишу це, нинішній Edge, заснований на EdgeHTML та Chakra, також не підтримує code, але Microsoft виконує заміну Edge на базі Blink - і V8 , що, імовірно, робить / буде.


Деякі браузери використовують keyCode, інші використовують which.

Якщо ви використовуєте jQuery, ви можете надійно використовувати, whichяк jQuery стандартизує речі ; Більше тут.

Якщо ви не використовуєте jQuery, ви можете зробити це:

var key = 'which' in e ? e.which : e.keyCode;

Або в якості альтернативи:

var key = e.which || e.keyCode || 0;

... який обробляє можливість, яка e.whichможе бути 0(відновивши його 0в кінці, використовуючи цікаво потужний ||оператор JavaScript ).


2
Спасибі TJ Де я можу знайти посилання на це? Не те, що я вам не вірю, мені просто цікаво! ... Я бачу, ви щойно додали це, дякую. Отже, навіть для тих, хто не використовує jquery, .що кращий вибір?
Скотт

7
@ScottE: Якщо ви не використовуєте jQuery, вам доведеться це вирішувати самостійно. Я зазвичай роблю це так, var key = event.which || event.keyCode;що використовуватиметься, event.whichякщо це визначено, а не фальси, або event.keyCodeякщо whichне визначено чи фальси. Технічно я, мабуть, повинен робити, var key = typeof event.which === "undefined" ? event.keyCode : event.which;але якщо event.whichє 0(чи може це бути 0?), Я навряд чи буду дбати про види справ, які я роблю.
TJ Crowder

2
@ScottE, ось основна довідка: quirksmode.org/js/keys.html (вона не включає which, що, на мою думку, надається лише jQuery, але я не впевнений на 100%, але це повинно почати вас бачити відмінності в браузерах)
Mottie

1
@fudgey: whichнадається keypressвсіма браузерами, крім IE. І химерність тут не є авторитетною. В якості посилання посилання, яке розмістив @TJ Crowder, набагато краще: unixpapa.com/js/key.html .
Тім Даун

5
@TJ Crowder: Так, whichвластивість події може дорівнювати нулю, і це може призвести до великої зміни для більшості програм. Наприклад, ключі, що не роздруковуються у Firefox, мають whichвластивість нуля та таке ж keyCodeвластивість, як і keydown. На keyCodeмоєму ПК у Firefox в домашній клавіші є 36, що є кодом символу для "$", що дозволить зробити неможливим розмежування між користувачем, який натискає клавішу "Головна", і користувачем, що вводить символ $ за допомогою event.which || event.keyCode.
Тім Даун

32

jQuery нормалізується event.whichзалежно від того event.which, підтримується він event.keyCodeчи event.charCodeпідтримується браузером:

// Add which for key events
if ( event.which == null && (event.charCode != null || event.keyCode != null) ) {
   event.which = event.charCode != null ? event.charCode : event.keyCode;
}

Додатковою перевагою .whichє те, що jQuery робить це і для клацання мишею:

// Add which for click: 1 === left; 2 === middle; 3 === right
// Note: button is not normalized, so don't use it
if ( !event.which && event.button !== undefined ) {
    event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
}

2
var key = event.which || event.charCode || event.keyCode
Енн ван Россум

@ anne-van-rossum, event.wich == null && ...тест лише для нульових чи невизначених. ваш event.wich || ...тест на хибність (undefined, null, false, 0, '' і т.д.)
aMarCruz

@aMarCruz Falsy спеціально. Наприклад, bugs.webkit.org/show_bug.cgi?id=16735 зі звітом Webkit 0. І я не думаю, що перевіряти ""чи []боляче.
Енн ван Россум

20

Якщо ви перебуваєте у ванільному Javascript, зауважте, що клавіша keyCode застаріла і буде знята:

Ця функція була видалена з веб-стандартів. Хоча деякі веб-переглядачі можуть все-таки підтримувати його, він перебуває в процесі випадання. Уникайте його використання та по можливості оновлюйте існуючий код; див. таблицю сумісності внизу цієї сторінки, щоб направити своє рішення. Майте на увазі, що ця функція може припинити роботу в будь-який час

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

Замість цього використовуйте або: .key або .code залежно від поведінки, яку ви хочете: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code https://developer.mozilla.org/en -US / docs / Web / API / KeyboardEvent / key

Обидва реалізовані на сучасних браузерах.


.code відповідає фізичному розташуванню клавіші на клавіатурі, тоді як .key відповідає символу, згенерованому натиснутою клавішею незалежно від місця розташування.
Крістофер

1
І "код", і "ключ" мають вигадки у сучасних браузерах. Використання прикладу "Спробуйте" на MDN developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code у різних браузерах показує, що IE11 / IE Edge не реалізує "код" та "ключ" реалізація не відповідає реалізації в Chrome / FF / Safari (різниці, як правило, полягають у контрольних символах типу Escape and Enter). Я думаю, що використання бібліотеки може бути найпростішим, якщо ви не готові самі рахувати ці капризи. Я дуже хочу, щоб це була відповідь, але IE
накручує

Хм ... насправді це не дуже погано, щоб реалізувати ключ в крос-браузерному способі. Звичайні буквено-цифрові клавіші просто повертають своє значення, а кнопки управління (втеча, введення, вкладка тощо) виявляються реалізованими однаково в більшості браузерів, крім IE11 / Edge, які реалізують старішу версію специфікації, тому принаймні є лише два можливі значення для кожного ключ.
Акрикос

Я б радив використовувати keyзамість цього code. Наприклад, якщо у вас є клавіатура з клавішами управління медіа, натискання кнопки Відтворення / пауза виводить "MediaPlayPause" для keyі "" для code.
туан

6

подивіться на це: https://developer.mozilla.org/en-US/docs/Web/API/event.keyCode

У випадку натискання клавіші значення Unicode натиснутої клавіші зберігається у властивості keyCode або charCode, ніколи і в обох. Якщо натиснута клавіша генерує символ (наприклад, "a"), charCode встановлюється в код цього символу, зважаючи на регістр букви. (тобто charCode враховує, чи утримується клавіша shift). В іншому випадку код натиснутої клавіші зберігається в keyCode. keyCode завжди встановлюється в подіях клавіатури та клавіатури. У цих випадках charCode ніколи не встановлюється. Щоб отримати код ключа незалежно від того, зберігався він у keyCode чи charCode, запитайте, яке властивість. Символи, введені через IME, не реєструються через keyCode або charCode.


6

event.keyНаразі рекомендую . Документи MDN: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key

event.KeyCodeі event.whichобидва мають неприємні застарілі попередження у верхній частині своїх сторінок MDN:
https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode https://developer.mozilla.org/en-US / docs / Web / API / KeyboardEvent /, який

Для буквено-цифрових ключів, event.keyсхоже, реалізовано однаково у всіх браузерах. Для керуючих клавіш (вкладка, введення, втеча тощо) event.keyмає однакове значення для Chrome / FF / Safari / Opera, але інше значення в IE10 / 11 / Edge (IE, мабуть, використовують старішу версію специфікації, але відповідають одна одній, як від 14 січня 2018 року).

Для буквено-цифрових ключів чек виглядатиме приблизно так:

event.key === 'a'

Для контрольних символів вам потрібно зробити щось на кшталт:

event.key === 'Esc' || event.key === 'Escape'

Я використовував приклад тут для тестування на декількох браузерах (мені довелося відкрити в codepen і відредагувати його для роботи з IE10): https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/ код

event.code згадується в іншій відповіді як можливість, але IE10 / 11 / Edge не реалізує її, тому це вирішено, якщо ви хочете підтримати IE.


2

Надійна бібліотека Javascript для фіксації вводу клавіатури та введених комбінацій клавіш. Він не має залежностей.

http://jaywcjlove.github.io/hotkeys/

hotkeys('ctrl+a,ctrl+b,r,f', function(event,handler){
    switch(handler.key){
        case "ctrl+a":alert('you pressed ctrl+a!');break;
        case "ctrl+b":alert('you pressed ctrl+b!');break;
        case "r":alert('you pressed r!');break;
        case "f":alert('you pressed f!');break;
    }
});

гарячі клавіші розуміє такі модифікатори: , shift, option, , alt, ctrl, control, command, і .

Наступні спеціальні клавіші можна використовувати для швидкого доступу: backspace, tab, clear, enter, return, esc, escape, space, up, down, left, right, home, end, pageup, pagedown, del, deleteі f1через f19.


Хоча це shim Array.prototype.indexOf, тому, якщо ви використовуєте це в іншій бібліотеці, воно може бути непридатним, оскільки воно змінює глобальну область застосування. Також, як видається, використовується застаріле event.keyCode.
Акрикос

Ця бібліотека не виявила Fn на моєму ноутбуці Vaio.
туан

0

У Firefox властивість keyCode не працює на події onkeypress (поверне лише 0). Для рішення крос-браузера використовуйте властивість разом з keyCode, наприклад:

var x = event.which || event.keyCode;  // Use either which or keyCode, depending on browser support
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.