.keyCode vs. .which

228

Ich dachte, dies würde irgendwo auf Stack Overflow beantwortet, aber ich kann es nicht finden.

Wenn ich auf ein Tastendruckereignis warte, sollte ich verwenden .keyCodeoder .whichfeststellen, ob die Eingabetaste gedrückt wurde?

Ich habe immer so etwas gemacht:

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

Aber ich sehe Beispiele, die .whichanstelle von verwenden .keyCode. Was ist der Unterschied? Ist einer browserübergreifender als der andere?

ScottE
quelle

Antworten:

209

Hinweis: Die folgende Antwort wurde im Jahr 2010 geschrieben. Hier viele Jahre später werden beide keyCodeund whichzugunsten von key(für den logischen Schlüssel) und code(für die physische Platzierung des Schlüssels) veraltet . Beachten Sie jedoch, dass der IE keine Unterstützung codebietet und die Unterstützung für keyeine ältere Version der Spezifikation basiert und daher nicht ganz korrekt ist. Während ich dies schreibe, wird der aktuelle Edge, der auf EdgeHTML und Chakra basiert, ebenfalls nicht unterstützt code, aber Microsoft führt seinen Blink- und V8- basierten Ersatz für Edge ein, der dies vermutlich tut / wird.


Einige Browser verwenden keyCode, andere verwenden which.

Wenn Sie jQuery verwenden, können Sie es zuverlässig verwenden, whichda jQuery die Dinge standardisiert . Mehr hier.

Wenn Sie jQuery nicht verwenden, können Sie Folgendes tun:

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

Oder alternativ:

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

... die die Möglichkeit behandelt, die e.whichmöglicherweise besteht 0(indem Sie diese 0am Ende mithilfe des merkwürdig leistungsstarken ||Operators von JavaScript wiederherstellen ).

TJ Crowder
quelle
2
Danke TJ Wo finde ich eine Referenz dafür? Nicht dass ich dir nicht glaube, ich bin nur neugierig! ... Ich sehe, du hast das gerade hinzugefügt, danke. Also, selbst für diejenigen, die jquery nicht verwenden, was ist eine bessere Wahl?
ScottE
7
@ScottE: Wenn Sie jQuery nicht verwenden, müssen Sie dies explizit selbst behandeln. Normalerweise mache ich das so. var key = event.which || event.keyCode;Das wird verwendet, event.whichwenn es definiert und nicht falsch ist oder event.keyCodewenn whiches undefiniert oder falsch ist. Technisch sollte ich es wahrscheinlich tun, var key = typeof event.which === "undefined" ? event.keyCode : event.which;aber wenn es so event.whichist 0(kann es sein 0?), Ist es unwahrscheinlich, dass ich mich um die Art von Dingen kümmere, die ich tue.
TJ Crowder
2
@ScottE, hier ist eine grundlegende Referenz: quirksmode.org/js/keys.html (nicht enthalten which, was meiner Meinung nach nur von jQuery bereitgestellt wird, aber ich bin nicht 100% sicher, aber es sollte Ihnen den Einstieg erleichtern Unterschiede in den Browsern)
Mottie
1
@fudgey: whichwird keypressvon allen Browsern außer IE bereitgestellt . Und der Quirksmode ist hier nicht maßgebend. Als Referenz ist der Link, den @TJ Crowder gepostet hat, viel besser: unixpapa.com/js/key.html .
Tim Down
5
@TJ Crowder: Ja, die whichEigenschaft des Ereignisses kann Null sein, und dies kann für die meisten Anwendungen einen großen Unterschied bedeuten. Beispielsweise haben nicht druckbare Schlüssel in Firefox die whichEigenschaft Null und dieselbe keyCodeEigenschaft wie keydown. Die Home-Taste hat keyCodeauf meinem PC in Firefox eine 36, was der Zeichencode für "$" ist. Dies würde es unmöglich machen, zwischen dem Benutzer, der die Home-Taste drückt, und dem Benutzer, der ein $ -Zeichen mit eingibt, zu unterscheiden event.which || event.keyCode.
Tim Down
32

jQuery Normalisiert event.whichje nachdem , ob event.which, event.keyCodeoder event.charCodewird vom Browser unterstützt:

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

Ein zusätzlicher Vorteil von .whichist, dass jQuery dies auch für Mausklicks tut:

// 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 ) ));
}
David Tang
quelle
2
var key = event.which || event.charCode || event.keyCode
Anne van Rossum
@ anne-van-rossum, teste event.wich == null && ...nur auf null oder undefiniert. Ihr event.wich || ...Test auf Falschheit (undefiniert, null, falsch, 0, '' usw.)
aMarCruz
@aMarCruz Falsy absichtlich. ZB bugs.webkit.org/show_bug.cgi?id=16735 mit Webkit-Berichten 0. Und ich glaube nicht, dass es nach etwas sucht ""oder []weh tut.
Anne van Rossum
20

Wenn Sie in Vanille-Javascript bleiben, beachten Sie bitte, dass keyCode jetzt veraltet ist und gelöscht wird:

Diese Funktion wurde aus den Webstandards entfernt. Obwohl einige Browser dies möglicherweise noch unterstützen, wird es gerade gelöscht. Vermeiden Sie die Verwendung und aktualisieren Sie den vorhandenen Code nach Möglichkeit. Informationen zu Ihrer Entscheidung finden Sie in der Kompatibilitätstabelle unten auf dieser Seite. Beachten Sie, dass diese Funktion jederzeit nicht mehr funktioniert

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

Verwenden Sie stattdessen entweder: .key oder .code, je nachdem, welches Verhalten Sie möchten: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code https://developer.mozilla.org/en -US / docs / Web / API / KeyboardEvent / key

Beide sind in modernen Browsern implementiert.

Slykat
quelle
.code entspricht der physischen Position der Taste auf der Tastatur, während .key dem Zeichen entspricht, das von der gedrückten Taste unabhängig von der Position generiert wird.
Christopher
1
Sowohl "Code" als auch "Schlüssel" haben in modernen Browsern Macken. Die Verwendung des Beispiels "Try it out" unter MDN developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code in verschiedenen Browsern zeigt, dass IE11 / IE Edge keinen "Code" und keinen "Schlüssel" implementiert. Die Implementierung stimmt nicht mit der Implementierung in Chrome / FF / Safari überein (Unterschiede scheinen hauptsächlich in Steuerzeichen wie Escape und Enter zu liegen). Ich denke, die Verwendung einer Bibliothek ist möglicherweise am einfachsten, wenn Sie nicht bereit sind, diese Unklarheiten selbst zu berücksichtigen. Ich möchte wirklich, dass dies die Antwort ist, aber IE vermasselt dies :-(
Akrikos
Hmm ... eigentlich sieht es gar nicht so schlecht aus, Schlüssel browserübergreifend zu implementieren. Normale alphanumerische Schlüssel geben nur ihren Wert zurück und für Steuerschlüssel (Escape, Enter, Tab usw.) werden sie in den meisten Browsern identisch implementiert, mit Ausnahme von IE11 / Edge, die eine ältere Version der Spezifikation implementieren, sodass für jeden nur zwei mögliche Werte vorhanden sind Schlüssel.
Akrikos
Ich würde empfehlen, keyanstelle von zu verwenden code. Wenn Sie beispielsweise eine Tastatur mit Mediensteuertasten haben, wird durch Drücken von Wiedergabe / Pause "MediaPlayPause" für keyund "" für ausgegeben code.
Donnerstag,
6

Schauen Sie sich das an: https://developer.mozilla.org/en-US/docs/Web/API/event.keyCode

In einem Tastendruckereignis wird der Unicode-Wert der gedrückten Taste entweder in der Eigenschaft keyCode oder charCode gespeichert, niemals in beiden. Wenn die gedrückte Taste ein Zeichen erzeugt (z. B. 'a'), wird charCode auf den Code dieses Zeichens gesetzt, wobei die Groß- und Kleinschreibung berücksichtigt wird. (dh charCode berücksichtigt, ob die Umschalttaste gedrückt gehalten wird). Andernfalls wird der Code der gedrückten Taste in keyCode gespeichert. keyCode wird immer in den Keydown- und Keyup-Ereignissen festgelegt. In diesen Fällen wird charCode niemals festgelegt. Um den Code des Schlüssels unabhängig davon abzurufen, ob er in keyCode oder charCode gespeichert wurde, fragen Sie die Eigenschaft which ab. Über einen IME eingegebene Zeichen werden nicht über keyCode oder charCode registriert.

Löwe
quelle
6

Ich würde event.keyderzeit empfehlen . MDN-Dokumente: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key

event.KeyCodeund event.whichbeide haben böse veraltete Warnungen oben auf ihren MDN-Seiten:
https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode https://developer.mozilla.org/en-US / docs / Web / API / KeyboardEvent / which

Für alphanumerische Schlüssel event.keyscheint in allen Browsern identisch implementiert zu sein. Für Steuerschlüssel (Tab, Eingabe, Escape usw.) gilt event.keyfür Chrome / FF / Safari / Opera derselbe Wert, in IE10 / 11 / Edge jedoch ein anderer Wert (IEs verwenden anscheinend eine ältere Version der Spezifikation, stimmen jedoch überein vom 14. Januar 2018).

Für alphanumerische Schlüssel würde ein Scheck ungefähr so ​​aussehen:

event.key === 'a'

Für Steuerzeichen müssten Sie Folgendes tun:

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

Ich habe das Beispiel hier verwendet, um es in mehreren Browsern zu testen (ich musste es in Codepen öffnen und bearbeiten, damit es mit IE10 funktioniert): https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/ Code

event.code wird in einer anderen Antwort als eine Möglichkeit erwähnt, aber IE10 / 11 / Edge implementiert es nicht, so dass es aus ist, wenn Sie IE-Unterstützung wünschen.

Akrikos
quelle
2

Eine robuste Javascript-Bibliothek zum Erfassen von Tastatureingaben und eingegebenen Tastenkombinationen. Es hat keine Abhängigkeiten.

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;
    }
});

Hotkeys versteht die folgenden Modifikatoren: , shift, option, , alt, ctrl, control, command, und .

Die folgenden Sondertasten können für Verknüpfungen verwendet werden: backspace, tab, clear, enter, return, esc, escape, space, up, down, left, right, home, end, pageup, pagedown, del,delete und f1durch f19.

小弟 调 调
quelle
Array.prototype.indexOf wird jedoch nicht angezeigt. Wenn Sie dies also in einer anderen Bibliothek verwenden, ist es möglicherweise nicht geeignet, da es den globalen Bereich ändert. Es scheint auch das veraltete zu verwenden event.keyCode.
Akrikos
Diese Bibliothek hat Fn auf meinem Vaio-Laptop nicht erkannt.
Donnerstag,
0

In Firefox funktioniert die keyCode-Eigenschaft beim Ereignis onkeypress nicht (gibt nur 0 zurück). Verwenden Sie für eine browserübergreifende Lösung die Eigenschaft which zusammen mit keyCode, z.

var x = event.which || event.keyCode;  // Use either which or keyCode, depending on browser support
Pankaj Chauhan
quelle