.keyCode vs. .which


228

Ho pensato che questo avrebbe avuto risposta da qualche parte su Stack Overflow, ma non riesco a trovarlo.

Se sto ascoltando un evento di pressione dei tasti, dovrei utilizzare .keyCodeo .whichper determinare se è stato premuto il tasto Invio?

Ho sempre fatto qualcosa di simile al seguente:

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

Ma vedo esempi che usano .whichinvece di .keyCode. Qual è la differenza? Uno è più cross-browser amichevole rispetto all'altro?


Risposte:


209

Nota: la risposta di seguito è stata scritta nel 2010. Qui, molti anni dopo, entrambi keyCodee whichsono deprecati a favore di key(per la chiave logica) e code(per il posizionamento fisico della chiave). Ma nota che IE non supporta codee il suo supporto keyè basato su una versione precedente delle specifiche, quindi non è del tutto corretto. Mentre scrivo questo, l'attuale Edge basato su EdgeHTML e Chakra non supporta codeneanche, ma Microsoft sta implementando la sua sostituzione Blink - e V8 - per Edge, che presumibilmente fa / volontà.


Alcuni browser usano keyCode, altri usano which.

Se stai usando jQuery, puoi usarlo in modo affidabile whichpoiché jQuery standardizza le cose ; Più qui

Se non stai usando jQuery, puoi farlo:

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

O in alternativa:

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

... che gestisce la possibilità che e.whichpotrebbe essere 0(ripristinandola 0alla fine, utilizzando l' ||operatore curiosamente potente di JavaScript ).


2
Grazie TJ Dove troverei un riferimento per questo? Non che non ti credo, sono solo curioso! ... Vedo che l'hai appena aggiunto, grazie. Quindi, anche per coloro che non usano jquery, qual è la scelta migliore?
ScottE,

7
@ScottE: se non si utilizza jQuery, è necessario gestirlo in modo esplicito. Di solito lo faccio in questo modo var key = event.which || event.keyCode;che userà event.whichse è definito e non falso, o event.keyCodese whichnon è definito o falso. Tecnicamente dovrei probabilmente farlo, var key = typeof event.which === "undefined" ? event.keyCode : event.which;ma se lo event.whichè 0(può essere 0?), È improbabile che mi occupi del tipo di cose che faccio.
TJ Crowder,

2
@ScottE, ecco un riferimento di base: quirksmode.org/js/keys.html (non include which, che penso sia fornito solo da jQuery ma non sono sicuro al 100%, ma dovrebbe iniziare a vedere differenze nei browser)
Mottie,

1
@fudgey: whichè fornito keypressda tutti i browser tranne IE. E quirksmode non è autorevole qui. Come riferimento, il link che @TJ Crowder ha pubblicato è molto meglio: unixpapa.com/js/key.html .
Tim Down

5
@TJ Crowder: Sì, la whichproprietà dell'evento può essere zero e questo può fare una grande differenza per la maggior parte delle applicazioni. Ad esempio, le chiavi non stampabili in Firefox hanno una whichproprietà pari a zero e la stessa keyCodeproprietà di keydown. Il tasto Home ha un keyCode36 di sul mio PC in Firefox, che è il codice carattere per "$", il che renderebbe impossibile distinguere tra l'utente premendo il tasto Home e l'utente digitando un carattere $ usando event.which || event.keyCode.
Tim Down

32

jQuery normalizza event.whicha seconda se event.which, event.keyCodeo event.charCodeè supportato dal browser:

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

Un ulteriore vantaggio .whichè che jQuery lo fa anche per i clic del mouse:

// 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,

@ anne-van-rossum, event.wich == null && ...prova solo per null o non definito. il tuo event.wich || ...test per falsy (undefined, null, false, 0, '', ecc.)
aMarCruz,

@aMarCruz Falsy apposta. Ad esempio bugs.webkit.org/show_bug.cgi?id=16735 con report Webkit 0. E non penso di controllare ""o fare []male.
Anne van Rossum,

20

Se rimani in Javascript vanilla, tieni presente che keyCode è ora obsoleto e verrà eliminato:

Questa funzione è stata rimossa dagli standard Web. Sebbene alcuni browser possano ancora supportarlo, è in procinto di essere eliminato. Evita di usarlo e aggiorna il codice esistente se possibile; vedere la tabella di compatibilità in fondo a questa pagina per guidare la tua decisione. Tieni presente che questa funzione potrebbe smettere di funzionare in qualsiasi momento

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

Utilizzare invece: .key o .code in base al comportamento desiderato: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code https://developer.mozilla.org/en -US / docs / Web / API / KeyboardEvent / chiave

Entrambi sono implementati su browser moderni.


.code corrisponde alla posizione fisica del tasto sulla tastiera mentre .key corrisponde al carattere generato dal tasto premuto indipendentemente dalla posizione.
Christopher,

1
Sia 'code' che 'key' hanno stranezze nei browser moderni. Utilizzando l'esempio "Provalo" su MDN developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code in diversi browser mostra che IE11 / IE Edge non implementano 'code' e la 'chiave' l'implementazione non corrisponde all'implementazione in Chrome / FF / Safari (le differenze sembrano essere principalmente nei personaggi di controllo come Escape e Enter). Penso che usare una biblioteca potrebbe essere più semplice a meno che tu non sia disposto a rendere conto di questi capricci da solo. Voglio davvero che questa sia la risposta, ma IE
rovina

Hmm ... in realtà non sembra troppo male implementare la chiave in un modo cross-browser. I normali tasti alfanumerici restituiscono semplicemente il loro valore e per i tasti di controllo (escape, enter, tab, ecc.) Appaiono implementati in modo identico nella maggior parte dei browser tranne IE11 / Edge che implementano una versione precedente delle specifiche, quindi almeno ci sono solo due valori possibili per ciascuno chiave.
Akrikos,

Consiglierei di utilizzare keyinvece di code. Ad esempio, se si dispone di una tastiera con i tasti di controllo multimediale, premendo Riproduci / Pausa vengono emessi "MediaPlayPause" per keye "" per code.
thdoan

6

guarda questo: https://developer.mozilla.org/en-US/docs/Web/API/event.keyCode

In un evento keypress, il valore Unicode del tasto premuto viene memorizzato nella proprietà keyCode o charCode, mai entrambe. Se il tasto premuto genera un carattere (ad es. 'A'), charCode viene impostato sul codice di quel carattere, rispettando il maiuscolo / minuscolo. (ad es. charCode tiene conto del fatto che il tasto shift è tenuto premuto). Altrimenti, il codice del tasto premuto viene memorizzato in keyCode. keyCode è sempre impostato negli eventi keydown e keyup. In questi casi, charCode non è mai impostato. Per ottenere il codice della chiave indipendentemente dal fatto che sia stata memorizzata in keyCode o charCode, richiedere quale proprietà. I caratteri immessi tramite un IME non si registrano tramite keyCode o charCode.


6

Consiglierei al event.keymomento. Documenti MDN: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key

event.KeyCodeed event.whichentrambi hanno cattivi avvisi deprecati nella parte superiore delle loro pagine MDN:
https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode https://developer.mozilla.org/en-US / docs / Web / API / KeyboardEvent / che

Per le chiavi alfanumeriche, event.keysembra essere implementato in modo identico in tutti i browser. Per i tasti di controllo (tab, enter, escape, ecc.), event.keyHa lo stesso valore su Chrome / FF / Safari / Opera ma un valore diverso in IE10 / 11 / Edge (apparentemente gli IE utilizzano una versione precedente delle specifiche ma si corrispondono tra loro come del 14 gennaio 2018).

Per i tasti alfanumerici un segno di spunta sarebbe simile a:

event.key === 'a'

Per i personaggi di controllo dovresti fare qualcosa del tipo:

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

Ho usato l'esempio qui per testare su più browser (ho dovuto aprire in codepen e modificarlo per farlo funzionare con IE10): https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/ codice

event.code è menzionato in una risposta diversa come possibilità, ma IE10 / 11 / Edge non la implementano, quindi è disponibile se si desidera il supporto IE.


2

Una robusta libreria Javascript per acquisire input da tastiera e combinazioni di tasti immessi. Non ha dipendenze.

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

tasti di scelta rapida comprende i seguenti modificatori: , shift, option, , alt, ctrl, control, command, e .

I tasti speciali seguenti possono essere usati per i collegamenti: backspace, tab, clear, enter, return, esc, escape, space, up, down, left, right, home, end, pageup, pagedown, del, deletee f1attraverso f19.


Tuttavia, shim Array.prototype.indexOf, quindi se lo si utilizza in un'altra libreria, potrebbe non essere adatto in quanto modifica l'ambito globale. Sembra anche usare il deprecato event.keyCode.
Akrikos,

Questa libreria non ha rilevato Fn sul mio laptop Vaio.
thdoan

0

In Firefox, la proprietà keyCode non funziona sull'evento onkeypress (restituirà solo 0). Per una soluzione cross-browser, utilizzare la proprietà which insieme a keyCode, ad esempio:

var x = event.which || event.keyCode;  // Use either which or keyCode, depending on browser support
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.