onKeyPress vs. onKeyUp e onKeyDown


329

Qual è la differenza tra questi tre eventi? Su Google ho scoperto che:

  • L' onKeyDownevento viene attivato quando l'utente preme un tasto.
  • L' onKeyUpevento viene attivato quando l'utente rilascia una chiave.
  • L' onKeyPressevento viene attivato quando l'utente preme e rilascia un tasto ( onKeyDownseguito da onKeyUp).

Capisco i primi due, ma non è onKeyPresslo stesso di onKeyUp? È possibile rilasciare un tasto ( onKeyUp) senza premerlo ( onKeyDown)?

Questo è un po 'confuso, qualcuno può chiarire questo per me?


3
Ho scoperto che se tengo premuto il tasto TAB che cicla continuamente attraverso tutti i campi e innesca solo 'onkeydown'.
nu everest,

23
L'evento keypress rappresenta un carattere digitato che può essere utilizzato per l'input, ad esempio "a", "D", "£", "©" e così via. D'altra parte, gli eventi di keydown e keyup rappresentano QUALSIASI chiave digitata, che include elementi come backspace, tab, su, giù, home, end e così via.
skcin7,

2
"(o è possibile rilasciare un tasto (KeyUp) senza premere (KeyDown) esso?)" - Sì. Ad esempio, il tasto tab: l'evento keyup potrebbe non essere acquisito dallo stesso elemento del keydown.
Self Evident,

Risposte:


191

Controlla qui per il link archiviato originariamente utilizzato in questa risposta.

Da quel link:

In teoria, gli eventi onKeyDowne onKeyUprappresentano i tasti premuti o rilasciati, mentre l' onKeyPressevento rappresenta un personaggio che viene digitato. L'implementazione della teoria non è la stessa in tutti i browser.


18
Metti insieme un jsfiddle basato sul post di @ Falk per dimostrare le idiosincrasie (usando jquery): jsfiddle.net/zG9MF/2
fordareh

Non riesco a vedere la pagina collegata, ma il punto su "un personaggio che viene digitato" è importante se prevedi di utilizzarlo per qualsiasi tipo di convalida. L'evento keypress non si attiva quando l'utente elimina un personaggio, quindi la tua validazione non si attiva.
Tony Merryfield,

@Tony Merryfield - il collegamento funziona bene per me, l'ho appena verificato di nuovo.
dcp,

1
@dcp - Sì, è bastato un suggerimento per farmi sulla strada giusta. Ho appena aggiunto il mio commento per rafforzare il punto che l'evento si innesca solo quando un personaggio viene digitato in contrapposizione a qualsiasi tasto premuto - hai ottenuto il mio voto;)
Tony Merryfield,

1
Inoltre, premendo "a lungo" un tasto, l'evento KeyDown continua a essere attivato fino a quando il tasto non viene rilasciato, nel qual caso KeyUp viene attivato una sola volta;)
Bernoulli IT

195

KeyPress, KeyUpE KeyDownsono analoghi a, rispettivamente: Click, MouseUp,e MouseDown.

  1. Down succede prima
  2. Press accade per secondo (quando viene inserito il testo)
  3. Up accade per ultimo (quando l'inserimento del testo è completo).

L'eccezione è webkit , che contiene un evento aggiuntivo:

keydown
keypress
textInput     
keyup

Di seguito è riportato uno snippet che puoi utilizzare per vedere tu stesso quando gli eventi vengono generati:

window.addEventListener("keyup", log);
window.addEventListener("keypress", log);
window.addEventListener("keydown", log);

function log(event){
  console.log( event.type );
}


1
Quindi, KeyPress è solo un evento in più che è KeyDown e TextInput? In che modo (KeyPress) viene generalmente utilizzato dagli sviluppatori?
instantsetsuna,

78
+1 migliore risposta - Il primo tasto * viene visualizzato per primo, il tasto * viene visualizzato per secondo (quando viene inserito il testo) e l'ultimo * viene visualizzato per ultimo (quando l'inserimento del testo è completo).
Scott Pelak,

2
-1 perché una piccola sperimentazione nello snippet contraddice la tua analogia con l'evento "click". L'evento "click" viene generato contemporaneamente a "mouseup" (quando si rilascia il pulsante del mouse), ma l'evento "keypress" viene generato contemporaneamente a "keydown" (quando il tasto viene premuto per la prima volta).
Mark Amery,

2
@Robusto In realtà, agli eventi keypresse viene keydownletteralmente assegnato lo stesso .timeStampvalore, che è accurato a intervalli di 5 microsecondi, ma non è comunque il mio punto. Il mio punto è che l' clickevento non si attiva fino a quando non si rilascia il pulsante del mouse, quindi dire che keypressè la versione della tastiera di clickfa sembrare keypressche allo stesso modo non si attiverà fino a quando non si rilascia il tasto. In realtà, non è così: si attiva quando il tasto viene premuto, proprio come keydownfa. Quindi keypressin realtà non è affatto analogo click.
Mark Amery,

2
@Robusto "come spieghi il 'keypress' sempre registrato dopo il 'keydown'" - semplice: la stessa azione dell'utente (premendo un tasto) innesca immediatamente entrambi i gestori da inserire nella coda degli eventi, ma in un ordine fisso . "vuoi solo avere una discussione per amor di discussione" - Eh? La tesi nucleo del vostro risposta è che keypress, keyupe keydownsono analoghi a click, mouseupe mousedown. La naturale interpretazione di ciò, secondo me, è che si keypressaccende nello stesso istante di keyup(proprio come clicke mouseup). Che cosa ha fatto dire, se non questo?
Mark Amery,

23

La maggior parte delle risposte qui sono focalizzate più sulla teoria che sulle questioni pratiche e ci sono alcune grandi differenze tra keyupe keypressper quanto riguarda i valori dei campi di input, almeno in Firefox (testato in 43).

Se l'utente digita 1in un elemento di input vuoto:

  1. Il valore dell'elemento di input sarà una stringa vuota (vecchio valore) all'interno del keypressgestore

  2. Il valore dell'elemento di input sarà 1(nuovo valore) all'interno del keyupgestore.

Ciò è di fondamentale importanza se si sta facendo qualcosa che si basa sulla conoscenza del nuovo valore dopo l'input anziché sul valore corrente come la convalida in linea o la tabulazione automatica.

Scenario:

  1. L'utente digita 12345in un elemento di input.
  2. L'utente seleziona il testo 12345.
  3. L'utente digita la lettera A.

Quando l' keypressevento si attiva dopo aver inserito la lettera A, la casella di testo ora contiene solo la lettera A.

Ma:

  1. Field.val () è 12345.
  2. $ Field.val (). Lunghezza è 5
  3. La selezione dell'utente è una stringa vuota (che impedisce di determinare cosa è stato eliminato sovrascrivendo la selezione).

Quindi sembra che il browser (Firefox 43) cancella la selezione dell'utente, quindi attiva l' keypressevento, quindi aggiorna il contenuto dei campi, quindi si attiva keyup.


16

onkeydownviene attivato quando il tasto è inattivo (come nelle scorciatoie; ad esempio, in Ctrl+A, Ctrlviene tenuto premuto "in basso".

onkeyup viene attivato quando viene rilasciato il tasto (compresi i tasti modificatore / etc)

onkeypressviene attivato come una combinazione di onkeydowne onkeyup, o in base alla ripetizione della tastiera (quando onkeyupnon viene attivato). (questo comportamento ripetuto è qualcosa che non ho testato. Se lo fai, aggiungi un commento!)

textInput(solo webkit) viene attivato quando viene inserito del testo (ad esempio, Shift+Ainserisce la lettera "A" maiuscola, ma Ctrl+Aseleziona il testo e non immette alcun input di testo. In tal caso, vengono attivati ​​tutti gli altri eventi)


1
Ho appena confermato che, in effetti, "onkeypress" viene chiamato ripetutamente quando si tiene premuto il tasto e si verifica la "ripetizione della tastiera". Tuttavia, questo vale anche per "onkeydown"! (che è inaspettato, dato il nome)
Venryx

11

Innanzitutto, hanno un significato diverso: sparano:

  • KeyDown: quando una chiave è stata premuta verso il basso
  • KeyUp - quando è stato rilasciato un pulsante premuto e dopo l'aggiornamento del valore di input / textarea (l'unico tra questi)
  • KeyPress - tra quelli e in realtà non significa che un tasto sia stato premuto e rilasciato (vedi sotto).

Secondo, alcuni tasti attivano alcuni di questi eventi e non altri . Per esempio,

  • Ignora KeyPress delete, frecce, PgUp/ PgDn, home/ end, ctrl, alt, shiftecc mentre KeyDown e KeyUp non (vedi dettagli sul escsottostante);
  • quando si cambia finestra tramite alt+ tabin Windows, solo KeyDown per gli altincendi perché la commutazione della finestra avviene prima di qualsiasi altro evento (e KeyDown per tabè impedito dal sistema, suppongo, almeno in Chrome 71).

Inoltre, dovresti tenere presente che event.keyCode(e event.which) di solito hanno lo stesso valore per KeyDown e KeyUp ma uno diverso per KeyPress. Prova il parco giochi che ho creato. A proposito, ho notato una stranezza: in Chrome, quando premo ctrl+ ae input/ textareaè vuoto, KeyPress si attiva con event.keyCode(e event.which) uguale a 1! (quando l'ingresso non è vuoto, non si attiva affatto).

Infine, ci sono alcune pragmatiche :

  • Per gestire le frecce, probabilmente dovrai usare onKeyDown: se l'utente tiene , KeyDown si attiva più volte (mentre KeyUp si attiva solo una volta quando rilasciano il pulsante). Inoltre, in alcuni casi è possibile impedire facilmente la propagazione di KeyDown ma non è possibile (o non è così facile) impedire la propagazione di KeyUp (ad esempio, se si desidera inviare su invio senza aggiungere newline al campo di testo).
  • Sorprendentemente, quando si tiene premuto un tasto, diciamo textarea, sia KeyPress che KeyDown si attivano più volte (Chrome 71), utilizzare KeyDown se ho bisogno dell'evento che si attiva più volte e KeyUp per il rilascio di un singolo tasto.
  • KeyDown è in genere migliore per i giochi quando devi fornire una migliore reattività alle loro azioni.
  • escdi solito è trasformati tramite KeyDown: KeyPress non lo fa fuoco e TastoSu comporta in modo diverso per inputs e textareas in diversi browser (per lo più a causa della perdita di messa a fuoco)
  • Se desideri adattare l'altezza di un'area di testo al contenuto, probabilmente non userai onKeyDown ma piuttosto suKeyPress ( PS ok, in realtà è meglio usare onChange per questo caso ).

Ho usato tutti e 3 i miei progetti, ma sfortunatamente potrei aver dimenticato alcuni pragmatici. (da notare: c'è anche inputed changeeventi)


Non avevo pensato di aggiungere keyline al contenuto del campo keyup, ma in realtà è importante.
FK Internet dal

10

Questo articolo di Jan Wolter è il pezzo migliore che abbia mai trovato, puoi trovare la copia archiviata qui se il link è morto.

Spiega molto bene tutti gli eventi chiave del browser,

L' evento keydown si verifica quando viene premuto il tasto, seguito immediatamente dall'evento keypress. Quindi l' evento keyup viene generato al rilascio della chiave.

Per comprendere la differenza tra keydown e keypress , è utile distinguere tra caratteri e tasti . Un tasto è un pulsante fisico sulla tastiera del computer. Un personaggio è un simbolo digitato premendo un pulsante. Su una tastiera americana, premere il 4tasto mentre si tiene premuto il Shifttasto produce in genere un carattere "simbolo del dollaro". Questo non è necessariamente il caso di tutte le tastiere del mondo. In teoria, gli eventi keydown e keyup rappresentano i tasti premuti o rilasciati, mentre il tasto premeevento rappresenta un personaggio che viene digitato. In pratica, non è sempre così che viene implementato.

Per un po ', alcuni browser hanno lanciato un evento aggiuntivo, chiamato textInput , subito dopo la pressione del tasto . Le prime versioni dello standard DOM 3 intendevano sostituirlo all'evento keypress , ma l'intera nozione fu successivamente revocata. Webkit lo supportava tra le versioni 525 e 533 e mi è stato detto che IE lo supportava, ma non l'ho mai rilevato, probabilmente perché Webkit richiedeva che si chiamasse textInput mentre IE lo chiamava textinput .

C'è anche un evento chiamato in ingresso , supportato da tutti i browser, che viene sparato subito dopo viene apportata una modifica ad una textarea campo o di input. Generalmente il tasto verrà attivato, quindi il carattere digitato verrà visualizzato nell'area di testo, quindi verrà attivato l'input. L' evento di input in realtà non fornisce alcuna informazione su quale chiave è stata digitata - dovresti ispezionare la casella di testo per capire cosa è cambiato - quindi non lo consideriamo davvero un evento chiave e non lo documentiamo qui . Sebbene sia stato originariamente definito solo per textareas e caselle di input, credo che ci sia qualche movimento verso la generalizzazione per sparare anche su altri tipi di oggetti.


La migliore risposta, quindi come puoi ottenere, per esempio, il simbolo del simbolo del dollaro dal tasto premuto?
bluejayke,

10

Sembra che onkeypress e onkeydown facciano lo stesso (con la piccola differenza dei tasti di scelta rapida già menzionati sopra).

Puoi provare questo:

<textarea type="text" onkeypress="this.value=this.value + 'onkeypress '"></textarea>
<textarea type="text" onkeydown="this.value=this.value + 'onkeydown '" ></textarea>
<textarea type="text" onkeyup="this.value=this.value + 'onkeyup '" ></textarea>

E vedrai che gli eventi onkeypress e onkeydown sono entrambi attivati ​​mentre viene premuto il tasto e non quando viene premuto il tasto.

La differenza è che l'evento viene attivato non una volta ma molte volte (finché si tiene premuto il tasto). Sii consapevole di ciò e gestiscili di conseguenza.


Ctrl, Shift, CapsLock, Backspace e altri tasti che non digitano qualcosa non causano unkeypress evento, ma attivano sempre a keydown.
CPHPython,

8

L'evento onkeypress funziona per tutti i tasti tranne ALT, CTRL, SHIFT, ESC in tutti i browser in cui l'evento onkeydown funziona per tutti i tasti. Significa che l'evento onkeydown cattura tutte le chiavi.


keypress ignora anche cancella, frecce, home / end, PgUp / PgDn, vedi la mia risposta per i dettagli (potresti voler aggiornare anche la tua risposta)
YakovL

4

Volevo solo condividere una curiosità:

quando si utilizza l'evento onkeydown per attivare un metodo JS, il charcode per quell'evento NON è uguale a quello che si ottiene con onkeypress!

Ad esempio i tasti del tastierino numerico restituiranno gli stessi caratteri dei tasti numerici sopra i tasti delle lettere quando si usa onkeypress, ma NON quando si usa onkeydown!

Mi ci sono voluti alcuni secondi per capire perché il mio script che controllava determinati codici di caratteri non è riuscito quando si utilizza onkeydown!

Demo: https://www.w3schools.com/code/tryit.asp?filename=FMMBXKZLP1MK

e sì. So che la definizione dei metodi è diversa .. ma la cosa molto confusa è che in entrambi i metodi il risultato dell'evento viene recuperato usando event.keyCode .. ma non restituiscono lo stesso valore .. non molto attuazione dichiarativa.


Sembra che le cose siano le stesse per Numeric Character ( 0123456789)
Mrigank Pawagi il

E hai notato che keyDown fornisce il KEY sulla tastiera, mentre keyPress fornisce il carattere esatto che abbiamo appena digitato (o fatto clic)
Mrigank Pawagi

2

Fondamentalmente, questi eventi agiscono in modo diverso su diversi tipi e versioni di browser, ho creato un piccolo test jsBin e puoi controllare la console per scoprire come si comportano questi eventi per il tuo ambiente di destinazione, spero che questo aiuto. http://jsbin.com/zipivadu/10/edit


1

Risposta aggiornata:

KeyDown

  • Spara più volte quando si tengono premuti i tasti.
  • Firma meta chiave.

KeyPress

  • Spara più volte quando si tengono premuti i tasti.
  • Non non sparare le chiavi meta.

KeyUp

  • Spara una volta alla fine quando si rilascia la chiave.
  • Firma meta chiave.

Questo è il comportamento in entrambi addEventListenere jQuery.

https://jsbin.com/vebaholamu/1/edit?js,console,output <- prova l'esempio

mostra un esempio tenendo premuto per SSS

(la risposta è stata modificata con la risposta corretta, screenshot ed esempio)


Tranne il keydown che spara anche più volte
bluejayke

-1, perché almeno un dettaglio su questo è sbagliato in almeno Chrome; come dice @bluejayke, KeyDown si attiva ripetutamente anche quando si tiene premuto un tasto.
Mark Amery,

Sì ragazzi avete ragione, scusate il mio errore; risposta modificata.
Quang Van,

0

Alcuni fatti pratici che potrebbero essere utili per decidere quale evento gestire (eseguire lo script di seguito e concentrarsi sulla casella di input):

$('input').on('keyup keydown keypress',e=>console.log(e.type, e.keyCode, e.which, e.key))
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input/>

Pressing:

  • i tasti di non inserimento / digitazione (ad es Shift. Ctrl) non attiveranno a keypress. Premere Ctrle rilasciarlo:

    keydown 17 17 Controllo

    keyup 17 17 Controllo

  • i tasti delle tastiere che applicano trasformazioni di caratteri ad altri caratteri possono portare a "Tasti" morti e duplicati (ad es ~. ´) keydown. Premere ´e rilasciare per visualizzare un doppio ´´:

    keydown 192 192 Dead

    keydown 192 192 ´´

    tasto 180 180 ´

    tasto 180 180 ´

    keyup 192 192 Dead

Inoltre, gli input non digitabili (ad es. A distanza <input type="range">) attiveranno comunque tutti gli eventi keyup, keydown e keypress in base ai tasti premuti.

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.