.keyCode vs. .which

228

Я думал, что на это ответят где-нибудь в переполнении стека, но я не могу его найти.

Если я слушаю событие нажатия клавиши, должен ли я использовать .keyCodeили .whichопределить, была ли нажата клавиша Enter?

Я всегда делал что-то вроде следующего:

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

Но я вижу примеры, которые используют .whichвместо .keyCode. Какая разница? Один кросс-браузер более дружественный, чем другой?

ScottE
источник
1
Оба они считаются устаревшими, к вашему сведению. developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/which developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode
CodeFinity

Ответы:

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 ||оператор ).

TJ Crowder
источник
2
Спасибо TJ Где я могу найти ссылку для этого? Не то чтобы я тебе не верила, мне просто любопытно! ... Я вижу, вы только что добавили это, спасибо. Так что, даже для тех, кто не использует jquery, какой вариант лучше?
Скотт
7
@ScottE: Если вы не используете jQuery, вы должны сами разобраться с этим. Я обычно делаю это так, var key = event.which || event.keyCode;что буду использовать, event.whichесли оно определено, а не false, или event.keyCodeесли whichundefined или false. Технически я, вероятно, должен делать, 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моем ПК клавиша Home имеет значение 36, что представляет собой код символа «$», что делает невозможным различение пользователя, нажимающего клавишу Home, и пользователя, набирающего символ $ с помощью 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 || ...тест на ложность (неопределенный, ноль , ложь, 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 / документы / Web / API / KeyboardEvent / ключ

Оба реализованы в современных браузерах.

slykat
источник
.code соответствует физическому расположению клавиши на клавиатуре, тогда как .key соответствует символу, генерируемому клавишей, независимо от местоположения.
Кристофер
1
И «код», и «ключ» имеют причуды в современных браузерах. Использование примера «Попробуйте» в MDN developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code в разных браузерах показывает, что IE11 / IE Edge не реализует «код» и «ключ» реализация не соответствует реализации в Chrome / FF / Safari (различия, по-видимому, в основном в управляющих символах, таких как Escape и Enter). Я думаю, что использование библиотеки может быть самым простым, если вы сами не готовы учесть эти причуды. Я действительно хочу, чтобы это было ответом, но IE это
испортил
Хм ... на самом деле это не так уж и плохо для реализации ключа кросс-браузерным способом. Обычные буквенно-цифровые ключи просто возвращают свое значение, и для управляющих клавиш (escape, enter, tab и т. Д.) Они реализованы одинаково в большинстве браузеров, кроме 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 всегда устанавливается в событиях keydown и keyup. В этих случаях charCode никогда не устанавливается. Чтобы получить код ключа независимо от того, был ли он сохранен в keyCode или charCode, запросите свойство which. Символы, введенные через 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 / документы / Web / API / KeyboardEvent / который

Для буквенно-цифровых ключей, event.keyкажется, реализован одинаково во всех браузерах. Для управляющих клавиш (tab, enter, escape и т. Д.) 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.

Akrikos
источник
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.

小弟 调 调
источник
Однако он делает Array.prototype.indexOf таким образом, поэтому, если вы используете это в другой библиотеке, он может не подойти, поскольку он изменяет глобальную область видимости. Похоже также использовать устаревший event.keyCode.
Акрикос,
Эта библиотека не обнаружила Fn на моем ноутбуке Vaio.
18:27
0

В Firefox свойство keyCode не работает с событием onkeypress (возвращает только 0). Для кросс-браузерного решения используйте свойство which вместе с keyCode, например:

var x = event.which || event.keyCode;  // Use either which or keyCode, depending on browser support
Панкадж Чаухан
источник