onKeyPress vs. onKeyUp i onKeyDown

329

Jaka jest różnica między tymi trzema wydarzeniami? Po googlowaniu stwierdziłem, że:

  • onKeyDownZdarzenie jest wywoływane, gdy użytkownik naciśnie klawisz.
  • onKeyUpZdarzenie jest wywoływane, gdy użytkownik zwolni klawisz.
  • onKeyPressZdarzenie jest wywoływane, gdy użytkownik naciska i zwalnia klawisz ( onKeyDownnastępnie onKeyUp).

Rozumiem pierwsze dwa, ale czy to nie onKeyPressto samo, co onKeyUp? Czy można zwolnić klawisz ( onKeyUp) bez naciskania go ( onKeyDown)?

To trochę mylące, czy ktoś może mi to wyjaśnić?

instantsetsuna
źródło
3
Przekonałem się, że przytrzymanie klawisza TAB powoduje ciągłe przełączanie między wszystkimi polami i wyzwala tylko „onkeydown”.
nve everest,
23
Zdarzenie keypress reprezentuje wpisywany znak, którego można używać do wprowadzania danych, na przykład „a”, „D”, „£”, „©” i tak dalej. Z drugiej strony, skróty klawiszowe i zdarzenia tworzenia kluczy reprezentują KAŻDY wpisywany klawisz, który obejmuje takie rzeczy, jak backspace, tab, góra, dół, home, koniec i tak dalej.
skcin7
2
„(czy jest możliwe zwolnienie klucza (KeyUp) bez naciskania go (KeyDown)?)” - Tak. Na przykład klawisz tab: zdarzenie keyup może nie zostać przechwycone przez ten sam element, co klawisz skrótu.
Self Evident

Odpowiedzi:

191

Sprawdź tutaj zarchiwizowany link pierwotnie użyty w tej odpowiedzi.

Z tego linku:

Teoretycznie zdarzenia onKeyDowni onKeyUpreprezentują naciśnięcie lub zwolnienie klawiszy, a onKeyPresszdarzenie oznacza wpisanie znaku. Implementacja teorii nie jest taka sama we wszystkich przeglądarkach.

dcp
źródło
18
Zbuduj jsfiddle na podstawie posta @ Falk, aby zademonstrować idiosynchracje (używając jquery): jsfiddle.net/zG9MF/2
fordareh
Nie widzę strony, do której prowadzi link, ale kwestia „wpisywanego znaku” jest ważna, jeśli planujesz używać go do dowolnego sprawdzania poprawności. Zdarzenie naciśnięcia klawisza nie jest uruchamiane, gdy użytkownik usuwa znak, więc sprawdzanie poprawności nie zostanie uruchomione.
Tony Merryfield,
@ Tony Merryfield - link działa dla mnie dobrze, właśnie go sprawdziłem.
dcp,
1
@dcp - Tak, było wystarczającą wskazówką, aby poprowadzić mnie na właściwą ścieżkę. Właśnie dodałem swój komentarz, aby podkreślić fakt, że zdarzenie uruchamia się tylko wtedy, gdy zostanie wpisana postać, a nie jakiekolwiek naciśnięcie klawisza - otrzymałeś moje poparcie;)
Tony Merryfield
1
Ponadto po „długim” naciśnięciu klawisza zdarzenie KeyDown jest uruchamiane do momentu zwolnienia klawisza, w którym to przypadku klawisz KeyUp jest uruchamiany tylko raz;)
Bernoulli IT
195

KeyPress, KeyUpI KeyDownsą analogiczne do odpowiednio: Click, MouseUp,i MouseDown.

  1. Down zdarza się pierwszy
  2. Press dzieje się na drugim miejscu (po wprowadzeniu tekstu)
  3. Up dzieje się na końcu (po zakończeniu wprowadzania tekstu).

Wyjątkiem jest webkit , który zawiera dodatkowe zdarzenie:

keydown
keypress
textInput     
keyup

Poniżej znajduje się fragment, którego możesz użyć, aby zobaczyć, kiedy zdarzenia zostaną uruchomione:

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

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

Robusto
źródło
1
Czy KeyPress to tylko dodatkowe zdarzenie, które jest czarno-białe KeyDown i TextInput? Jak to jest (KeyPress) ogólnie używane przez programistów?
instantsetsuna
78
+1 najlepsza odpowiedź - * Dół dzieje się jako pierwszy, * Naciśnięcie dzieje się jako drugi (po wprowadzeniu tekstu), a * Dół dzieje się jako ostatni (po zakończeniu wprowadzania tekstu).
Scott Pelak,
2
-1, ponieważ małe eksperymenty we fragmencie są sprzeczne z twoją analogią do zdarzenia „kliknięcia”. Zdarzenie „kliknięcie” jest uruchamiane w tym samym czasie, co „kliknięcie myszą” (po zwolnieniu przycisku myszy), ale zdarzenie „naciśnięcie klawisza” jest uruchamiane w tym samym czasie, co „naciśnięcie klawisza” (po pierwszym naciśnięciu klawisza).
Mark Amery
2
@Robusto Właściwie, keypressi keydownzdarzenia dosłownie mają przypisaną tę samą .timeStampwartość, co odpowiada dokładności co 5 mikrosekund, ale i tak nie o to mi chodzi. Chodzi mi o to, że clickzdarzenie nie jest uruchamiane, dopóki nie zwolnisz przycisku myszy, więc powiedzenie, że keypressjest to wersja klawiatury clicksprawia, że ​​brzmi, jakby keypressnie odpalał, dopóki nie zwolnisz klawisza. W rzeczywistości tak nie jest: uruchamia się, gdy klawisz jest wciśnięty, tak jak keydownrobi. Tak więc keypresswcale nie jest analogiczne do click.
Mark Amery
2
@Robusto „jak wyjaśnisz, że„ naciśnięcie klawisza ”jest zawsze rejestrowane po„ skrócie klawisza ”” - proste: ta sama akcja użytkownika (naciśnięcie klawisza) natychmiast powoduje, że oba moduły obsługi są wpychane do kolejki zdarzeń, ale w ustalonej kolejności . „po prostu chcesz mieć argument za argumentem” - Eh? Teza rdzeń odpowiedź jest taka, że keypress, keyupi keydownsą analogiczne do click, mouseup, i mousedown. Naturalną interpretacją tego jest dla mnie to, że keypressodpala w tym samym momencie co keyup(tak jak clicki mouseup). Co nie znaczy, że jeśli nie?
Mark Amery
23

Większość odpowiedzi tutaj skupia się bardziej na teorii niż na zagadnieniach praktycznych i istnieją duże różnice między wartościami pól wejściowych keyupi keypressco do nich, przynajmniej w Firefoksie (przetestowanym w 43).

Jeśli użytkownik wpisze 1pusty element wejściowy:

  1. Wartością elementu wejściowego będzie pusty ciąg (stara wartość) wewnątrz modułu keypressobsługi

  2. Wartość elementu wejściowego będzie 1(nowa wartość) wewnątrz modułu keyupobsługi.

Ma to kluczowe znaczenie, jeśli robisz coś, co opiera się na znajomości nowej wartości po danych wejściowych, a nie bieżącej wartości, np. Walidacja wbudowana lub automatyczne tabulowanie.

Scenariusz:

  1. Użytkownik wpisuje 12345element wejściowy.
  2. Użytkownik wybiera tekst 12345.
  3. Użytkownik wpisuje literę A.

Gdy keypresszdarzenie zostanie uruchomione po wprowadzeniu litery A, pole tekstowe zawiera teraz tylko literę A.

Ale:

  1. Field.val () to 12345.
  2. $ Field.val (). Długość wynosi 5
  3. Wybór użytkownika jest pustym ciągiem (uniemożliwiającym określenie, co zostało usunięte, poprzez zastąpienie wyboru).

Wygląda więc na to, że przeglądarka (Firefox 43) kasuje wybór użytkownika, następnie uruchamia keypresszdarzenie, następnie aktualizuje zawartość pól, a następnie odpala keyup.

Nacięcie
źródło
16

onkeydownjest zwolniony, gdy klucz jest w dół (jak w skrótach, na przykład w Ctrl+A, Ctrlodbywa się „w dół”.

onkeyup jest uruchamiany po zwolnieniu klawisza (w tym klawiszy modyfikatora / itp.)

onkeypressjest uruchamiany jako kombinacja onkeydowni onkeyuplub w zależności od powtarzania klawiatury (gdy onkeyupnie jest uruchamiany). (to powtarzające się zachowanie jest czymś, czego nie przetestowałem. Jeśli wykonasz test, dodaj komentarz!)

textInput(tylko webkit) jest uruchamiany, gdy wprowadzony jest jakiś tekst (na przykład Shift+Awpisuje wielkie litery „A”, ale Ctrl+Azaznacza tekst i nie wprowadza żadnego wprowadzania tekstu. W takim przypadku uruchamiane są wszystkie inne zdarzenia)

arunjitsingh
źródło
1
Właśnie potwierdziłem, że rzeczywiście „naciśnięcie klawisza” jest wywoływane wielokrotnie, gdy klawisz jest wciśnięty i następuje „powtarzanie klawiatury”. Dotyczy to jednak również „onkeydown”! (co jest nieoczekiwane, biorąc pod uwagę nazwę)
Venryx
11

Po pierwsze mają inne znaczenie: strzelają:

  • KeyDown - kiedy klawisz został wciśnięty w dół
  • KeyUp - po zwolnieniu wciśniętego przycisku i po zaktualizowaniu wartości input / textarea (jedynego spośród nich)
  • KeyPress - pomiędzy nimi i tak naprawdę nie oznacza, że klucz został wciśnięty i zwolniony (patrz poniżej).

Po drugie, niektóre klucze uruchamiają niektóre z tych zdarzeń, a inne nie . Na przykład,

  • Przyciśnięcie ignorowane delete, strzały, PgUp/ PgDn, home/ end, ctrl, alt, shiftitp podczas KeyDown i KeyUp nie (patrz szczegóły na temat escponiżej);
  • kiedy zmieniasz okno przez alt+ tabw Windows, tylko KeyDown dla altpożarów, ponieważ przełączanie okien odbywa się przed jakimkolwiek innym zdarzeniem (i KeyDown dla tabjest zapobiegany przez system, jak sądzę, przynajmniej w Chrome 71).

Należy również pamiętać, że event.keyCode(i event.which) zwykle mają tę samą wartość dla KeyDown i KeyUp, ale inną dla KeyPress. Wypróbuj plac zabaw , który stworzyłem. Nawiasem mówiąc, zauważyłem dziwne zachowanie: w Chrome, kiedy naciskam ctrl+, aa input/ textareajest puste, KeyPress strzela z event.keyCode(i event.which) równym 1! (gdy wejście nie jest puste, w ogóle się nie uruchamia).

Wreszcie, jest trochę pragmatyki :

  • Do obsługi strzałek prawdopodobnie będziesz musiał użyć onKeyDown: jeśli użytkownik przytrzyma klawisz , KeyDown strzela kilka razy (podczas gdy KeyUp uruchamia się tylko raz po zwolnieniu przycisku). Ponadto, w niektórych przypadkach możesz łatwo zapobiec propagacji KeyDown, ale nie możesz (lub nie możesz tak łatwo) zapobiec propagacji KeyUp (na przykład, jeśli chcesz przesłać przy wejściu bez dodawania nowego wiersza do pola tekstowego).
  • O dziwo, kiedy trzymasz klucz, powiedzmy textarea, KeyPress i KeyDown uruchamiają się wiele razy (Chrome 71), użyłbym KeyDown, jeśli potrzebuję zdarzenia, które uruchamia się wiele razy, i KeyUp do wydania pojedynczego klucza.
  • KeyDown jest zwykle lepszy dla gier, gdy musisz zapewnić lepszą reakcję na ich działania.
  • escjest zwykle przetwarzany przez KeyDown: KeyPress nie uruchamia się, a KeyUp zachowuje się inaczej dla inputsi textareasi różnych przeglądarkach (głównie z powodu utraty ostrości)
  • Jeśli chcesz dopasować wysokość pola tekstowego do treści, prawdopodobnie nie użyjesz onKeyDown, a raczej onKeyPress ( PS OK, w tym przypadku lepiej jest użyć onChange ).

Użyłem wszystkich 3 w moim projekcie, ale niestety mogłem zapomnieć o niektórych pragmatykach. (należy zauważyć: są też inputi changewydarzenia)

Jakow
źródło
Nie myślałem o dodaniu nowej linii do zawartości pola, ale to jest naprawdę ważne.
FKEinternet,
10

Ten artykuł Jana Woltera to najlepszy kawałek, z jakim się zetknąłem. Możesz znaleźć zarchiwizowaną kopię tutaj, jeśli link nie działa.

Bardzo dobrze wyjaśnia wszystkie kluczowe zdarzenia przeglądarki,

KeyDown zdarzenie gdy zostanie naciśnięty klawisz, a następnie natychmiast przypadku naciśnięcia klawisza. Następnie zdarzenie keyup jest generowane po zwolnieniu klucza.

Aby zrozumieć różnicę między keydown i naciśnięciu klawisza , warto rozróżnić znaków i kluczy . Klucz jest fizyczny przycisk na klawiaturze komputera. Znak jest symbolem wpisane przez naciśnięcie przycisku. Na klawiaturze amerykańskiej naciśnięcie 4klawisza i przytrzymanie Shiftklawisza zwykle powoduje powstanie znaku „dolara”. Nie musi tak być w przypadku każdej klawiatury na świecie. Teoretycznie zdarzenia keydown i keyup przedstawiają naciśnięcie lub zwolnienie klawiszy , a naciśnięcie klawiszaZdarzenie reprezentuje wpisywany znak. W praktyce nie zawsze jest to realizowane.

Przez chwilę niektórzy przeglądający uruchomili dodatkowe zdarzenie, o nazwie textInput , natychmiast po naciśnięciu klawisza . Wczesne wersje standardu DOM 3 miały to zastąpić zdarzenie naciśnięcia klawisza , ale cała koncepcja została później odwołana. Webkit obsługiwał to między wersjami 525 i 533 i powiedziano mi, że IE je wspierał, ale nigdy tego nie wykryłem , prawdopodobnie dlatego, że Webkit wymagał, aby nazywał się textInput, podczas gdy IE nazywał to textinput .

Istnieje również zdarzenie o nazwie input , obsługiwane przez wszystkie przeglądarki, które jest uruchamiane zaraz po zmianie w polu tekstowym lub polu wprowadzania. Zazwyczaj naciśnięcie klawisza będzie uruchamiane, następnie wpisany znak pojawi się w obszarze tekstowym, a następnie wprowadzony sygnał zostanie uruchomiony. Wejście wydarzenie w rzeczywistości nie daje żadnych informacji o tym, co zostało wpisane klucz - trzeba by zbadać pole tekstowe, aby zrozumieć to, co się zmieniło - tak naprawdę nie uważają jej kluczową zdarzenie i tak naprawdę nie dokumentują je tutaj . Chociaż pierwotnie został zdefiniowany tylko dla obszarów tekstowych i pól wprowadzania, uważam, że istnieje pewien ruch w kierunku uogólnienia go, aby strzelał także do innych typów obiektów.

Suraj Jain
źródło
Najlepsza odpowiedź, więc w jaki sposób można uzyskać, powiedzmy, symbol dolara po naciśnięciu klawisza?
bluejayke
10

Wydaje się, że onkeypress i onkeydown robią to samo (z niewielką różnicą skrótów klawiszowych wspomnianą powyżej).

Możesz spróbować:

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

Zobaczysz, że zdarzenia onkeypress i onkeydown są wyzwalane podczas naciskania klawisza, a nie po naciśnięciu klawisza.

Różnica polega na tym, że zdarzenie jest wyzwalane nie raz, ale wiele razy (o ile przytrzymasz wciśnięty klawisz). Bądź tego świadomy i postępuj z nimi odpowiednio.

Falk
źródło
Ctrl, Shift, CapsLock, Backspace i inne klawisze, które niczego niekeypress wpisują, nie powodują zdarzenia, ale zawsze uruchamiają keydown.
CPHPython
8

Zdarzenie onkeypress działa dla wszystkich klawiszy oprócz ALT, CTRL, SHIFT, ESC we wszystkich przeglądarkach, w których zdarzenie onkeydown działa dla wszystkich klawiszy. Oznacza, że ​​zdarzenie onkeydown przechwytuje wszystkie klucze.

Mohd Sadiq
źródło
przyciśnięcie również ignoruje kasowania, strzały, Home / End, PgUp / PgDn, zobacz moją odpowiedź dla detali (może chcesz zaktualizować swoją odpowiedź zbyt)
YakovL
4

Chciałem tylko podzielić się ciekawością:

kiedy używasz zdarzenia onkeydown do aktywacji metody JS, kod znaków dla tego zdarzenia NIE jest taki sam, jak ten, który otrzymujesz z onkeypress!

Na przykład klawisze numeryczne zwracają te same kody znaków, co klawisze numeryczne nad klawiszami literowymi podczas korzystania z funkcji onkeypress, ale NIE przy korzystaniu z funkcji onkeydown!

Zajęło mi to kilka sekund, aby dowiedzieć się, dlaczego mój skrypt sprawdzający niektóre znaki nie zadziałał podczas używania programu onkeydown!

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

i tak. Wiem, że definicje metod są różne .. ale bardzo mylące jest to, że w obu metodach wynik zdarzenia jest pobierany za pomocą event.keyCode .. ale nie zwracają tej samej wartości .. niezbyt wdrożenie deklaratywne.

Perkusista
źródło
Wygląda na to, że dla Znaków Numerycznych ( 0123456789) sytuacja jest taka sama
Mrigank Pawagi,
I czy zauważyłeś, że keyDown daje KLUCZ na klawiaturze, a keyPress daje dokładnie znak, który właśnie
wpisaliśmy
2

Zasadniczo te zdarzenia działają inaczej w zależności od typu i wersji przeglądarki, stworzyłem mały test jsBin i możesz sprawdzić konsolę, aby dowiedzieć się, jak te zdarzenia zachowują się w docelowym środowisku, mam nadzieję, że ta pomoc. http://jsbin.com/zipivadu/10/edit

Ken Chan
źródło
1

Zaktualizowana odpowiedź:

KeyDown

  • Wystrzeliwuje wiele razy, gdy przytrzymasz klawisze.
  • Odpala meta-klucz.

KeyPress

  • Wystrzeliwuje wiele razy, gdy przytrzymasz klawisze.
  • Czy nie ogień klucze meta.

KeyUp

  • Wystrzeliwuje raz na końcu po zwolnieniu klucza.
  • Odpala meta-klucz.

Jest to zachowanie zarówno addEventListeneri jQuery.

https://jsbin.com/vebaholamu/1/edit?js,console,output <- spróbuj przykład

pokazuje przykład z przytrzymaniem dla SSS

(odpowiedź została edytowana z poprawną odpowiedzią, zrzutem ekranu i przykładem)

Quang Van
źródło
Z wyjątkiem
skrótu klawiszowego,
-1, ponieważ co najmniej jeden szczegół jest nieprawidłowy w co najmniej Chrome; jak mówi @bluejayke, KeyDown również strzela wielokrotnie, gdy przytrzymasz klawisz.
Mark Amery
Tak, macie rację, przepraszam za mój błąd; odpowiedź zredagowana.
Quang Van
0

Kilka praktycznych faktów, które mogą być przydatne do podjęcia decyzji, które zdarzenie obsłużyć (uruchom skrypt poniżej i skup się na polu wprowadzania):

$('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/>

Groźny:

  • Klucze nie wstawianie / pisanie (na przykład Shift, Ctrl) nie wywoła keypress. Naciśnij Ctrli zwolnij:

    keydown 17 17 Kontrola

    keyup 17 17 Sterowanie

  • Klawisze z klawiatury, które mają zastosowanie do innych znaków transformacje postaci może prowadzić do trupów i powielać „Keys” (np ~, ´) w sprawie keydown. Naciśnij ´i zwolnij, aby wyświetlić podwójne ´´:

    keydown 192 192 Dead

    keydown 192 192 ´´

    naciśnięcie klawisza 180 180 ´

    naciśnięcie klawisza 180 180 ´

    keyup 192 192 Nie żyje

Dodatkowo, nietypowe dane wejściowe (np. Dystansowe <input type="range">) nadal będą wyzwalać wszystkie zdarzenia związane z wprowadzaniem klucza, naciśnięciem klawisza i naciśnięciem klawisza zgodnie z naciśniętymi klawiszami.

CPHPython
źródło