onKeyPress Vs. onKeyUp et onKeyDown

329

Quelle est la différence entre ces trois événements? Lors de la recherche sur Google, j'ai constaté que:

  • L' onKeyDownévénement est déclenché lorsque l'utilisateur appuie sur une touche.
  • L' onKeyUpévénement est déclenché lorsque l'utilisateur relâche une clé.
  • L' onKeyPressévénement est déclenché lorsque l'utilisateur appuie et relâche une touche ( onKeyDownsuivi de onKeyUp).

Je comprends les deux premiers, mais ce n'est pas onKeyPresspareil onKeyUp? Est-il possible de relâcher une touche ( onKeyUp) sans la presser ( onKeyDown)?

C'est un peu déroutant, quelqu'un peut-il clarifier cela pour moi?

instantsetsuna
la source
3
J'ai constaté que si je maintiens la touche TAB enfoncée, elle parcourt en continu tous les champs et ne déclenche que «onkeydown».
nu everest
23
L'événement keypress représente un caractère en cours de frappe qui peut être utilisé pour la saisie, tel que «a», «D», «£», «©», etc. D'un autre côté, les événements keydown et keyup représentent TOUTES les touches tapées, ce qui inclut des choses comme le retour arrière, la tabulation, le haut, le bas, la maison, la fin, etc.
skcin7
2
"(ou est-il possible de relâcher une touche (KeyUp) sans appuyer sur (KeyDown)?)" - Oui. Par exemple, la touche de tabulation: l'événement de keyup peut ne pas être capturé par le même élément que le keydown.
Self Evident

Réponses:

191

Vérifiez ici le lien archivé utilisé à l'origine dans cette réponse.

De ce lien:

En théorie, les événements onKeyDownet onKeyUpreprésentent les touches enfoncées ou relâchées, tandis que l' onKeyPressévénement représente un caractère en cours de frappe. La mise en œuvre de la théorie n'est pas la même dans tous les navigateurs.

dcp
la source
18
Mettre en place un jsfiddle basé sur le post de @ Falk pour démontrer les idiosynchracies (en utilisant jquery): jsfiddle.net/zG9MF/2
fordareh
Je ne peux pas voir la page liée, mais le point sur «un caractère en cours de frappe» est important si vous prévoyez de l'utiliser pour toute sorte de validation. L'événement keypress ne se déclenche pas lorsque l'utilisateur supprime un caractère, votre validation ne se déclenchera donc pas.
Tony Merryfield
@Tony Merryfield - le lien fonctionne bien pour moi, je viens de le vérifier à nouveau.
dcp
1
@dcp - Oui, c'était suffisant pour me mettre sur la bonne voie. Je viens d'ajouter mon commentaire pour renforcer le fait que l'événement ne se déclenche que lorsqu'un caractère est tapé par opposition à n'importe quelle pression sur une touche - vous avez obtenu mon vote positif;)
Tony Merryfield
1
De plus, lors d'une "longue" pression sur une touche, l'événement KeyDown continue de se déclencher jusqu'à ce que la touche soit relâchée, auquel cas KeyUp n'est déclenché qu'une seule fois;)
Bernoulli IT
195

KeyPress, KeyUpEt KeyDownsont analogues à, respectivement: Click, MouseUp,et MouseDown.

  1. Down arrive en premier
  2. Press arrive en second (lorsque le texte est entré)
  3. Up se produit en dernier (lorsque la saisie de texte est terminée).

L'exception est le webkit , qui contient un événement supplémentaire:

keydown
keypress
textInput     
keyup

Vous trouverez ci-dessous un extrait que vous pouvez utiliser pour voir par vous-même lorsque les événements sont déclenchés:

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

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

Robusto
la source
1
Donc, KeyPress est-il juste un événement supplémentaire qui est n / b KeyDown et TextInput? Comment est-il (KeyPress) généralement utilisé par les développeurs?
instantsetsuna
78
+1 meilleure réponse - Le * Down se produit en premier, le * Press se produit en second (lorsque le texte est entré) et le * Up se produit en dernier (lorsque la saisie de texte est terminée).
Scott Pelak
2
-1 car une petite expérimentation dans l'extrait contredit votre analogie avec l'événement "clic". L'événement 'click' se déclenche en même temps que 'mouseup' (lorsque vous relâchez le bouton de la souris), mais l'événement 'keypress' se déclenche en même temps que 'keydown' (lorsque la touche est enfoncée pour la première fois).
Mark Amery
2
@Robusto En fait, les événements keypresset keydownreçoivent littéralement la même .timeStampvaleur, qui est précise à des intervalles de 5 microsecondes, mais ce n'est pas vraiment mon point de toute façon. Mon point est que l' clickévénement ne se déclenche pas tant que vous ne relâchez pas le bouton de la souris, donc dire que keypressc'est la version du clavier clickqui le fait sonner keypressne se déclenchera pas jusqu'à ce que vous relâchiez la touche. En fait, ce n'est pas le cas: il se déclenche lorsque la touche est enfoncée, tout comme le keydownfait. Ce keypressn'est donc pas du tout analogue clickà tout.
Mark Amery
2
@Robusto "comment expliquez-vous que la" pression de touche "est toujours enregistrée après le" keydown "" - simple: la même action de l'utilisateur (en appuyant sur une touche) déclenche immédiatement les deux gestionnaires à être poussés dans la file d'attente des événements, mais dans un ordre fixe . "vous voulez juste avoir un argument pour le plaisir de l'argument" - Eh? La thèse principale de votre réponse est que keypress, keyupet keydownsont analogues à click, mouseupet mousedown. L'interprétation naturelle de cela, pour moi, est que cela se keypressdéclenche au même instant que keyup(tout comme clicket mouseup). Que vouliez - vous dire, sinon cela?
Mark Amery
23

La plupart des réponses ici sont davantage axées sur la théorie que sur les questions pratiques et il existe de grandes différences entre keyupet keypressen ce qui concerne les valeurs des champs de saisie, au moins dans Firefox (testé en 43).

Si l'utilisateur tape 1dans un élément d'entrée vide:

  1. La valeur de l'élément d'entrée sera une chaîne vide (ancienne valeur) à l'intérieur du keypressgestionnaire

  2. La valeur de l'élément d'entrée sera 1(nouvelle valeur) à l'intérieur du keyupgestionnaire.

Ceci est d'une importance critique si vous faites quelque chose qui repose sur la connaissance de la nouvelle valeur après l'entrée plutôt que sur la valeur actuelle, comme la validation en ligne ou la tabulation automatique.

Scénario:

  1. L'utilisateur tape 12345dans un élément d'entrée.
  2. L'utilisateur sélectionne le texte 12345 .
  3. L'utilisateur tape la lettre A.

Lorsque l' keypressévénement se déclenche après avoir saisi la lettre A, la zone de texte contient désormais uniquement la lettreA .

Mais:

  1. Field.val () est 12345 .
  2. $ Field.val (). La longueur est 5
  3. La sélection de l'utilisateur est une chaîne vide (vous empêchant de déterminer ce qui a été supprimé en écrasant la sélection).

Il semble donc que le navigateur (Firefox 43) efface la sélection de l'utilisateur, puis déclenche l' keypressévénement, puis met à jour le contenu des champs, puis se déclenche keyup.

pseudo
la source
16

onkeydownest déclenché lorsque la touche est enfoncée (comme dans les raccourcis; par exemple, dans Ctrl+A, Ctrlest maintenu enfoncé).

onkeyup est tiré lorsque la touche est relâchée (y compris les touches de modification / etc)

onkeypressest déclenché comme une combinaison de onkeydownet onkeyup, ou en fonction de la répétition du clavier (lorsqu'il onkeyupn'est pas déclenché). (ce comportement répété est quelque chose que je n'ai pas testé. Si vous testez, ajoutez un commentaire!)

textInput(webkit uniquement) est déclenché lorsque du texte est entré (par exemple, Shift+Aentrerait en majuscule «A», mais Ctrl+Asélectionnerait du texte et ne saisirait aucune entrée de texte. Dans ce cas, tous les autres événements sont déclenchés)

arunjitsingh
la source
1
Je viens de confirmer que, en effet, "onkeypress" est appelé à plusieurs reprises lorsque la touche est maintenue enfoncée et que la "répétition du clavier" se produit. Cependant, cela est également vrai pour "onkeydown"! (ce qui est inattendu, étant donné le nom)
Venryx
11

Tout d'abord, ils ont une signification différente: ils tirent:

  • KeyDown - lorsqu'une touche a été enfoncée
  • KeyUp - lorsqu'un bouton poussé a été relâché , et après la mise à jour de la valeur d'entrée / zone de texte (la seule parmi celles-ci)
  • KeyPress - entre ceux-ci et ne signifie pas réellement qu'une touche a été enfoncée et relâchée (voir ci-dessous).

Deuxièmement, certaines touches déclenchent certains de ces événements et n'en déclenchent pas d'autres . Par exemple,

  • Ignore KeyPress delete, flèches, PgUp/ PgDn, home/ end, ctrl, alt, shiftetc tout KeyDown et KeyUp ne (voir plus de détails suresc ci - dessous);
  • lorsque vous changez de fenêtre via alt+ tabdans Windows, uniquement KeyDown pour les altincendies car la commutation de fenêtre se produit avant tout autre événement (et KeyDown pour tabest empêché par le système, je suppose, au moins dans Chrome 71).

En outre, vous devez garder à l'esprit que event.keyCode(et event.which) ont généralement la même valeur pour KeyDown et KeyUp mais différente pour KeyPress. Essayez le terrain de jeu que j'ai créé. Soit dit en passant, j'ai remarqué une bizarrerie: dans Chrome, lorsque j'appuie sur ctrl+ aet que le input/ textareaest vide, pour KeyPress se déclenche avec event.keyCode(et event.which) égal à 1! (lorsque l'entrée n'est pas vide, elle ne se déclenche pas du tout).

Enfin, il y a quelques pragmatiques :

  • Pour gérer les flèches, vous devrez probablement utiliser onKeyDown: si l'utilisateur le maintient , KeyDown se déclenche plusieurs fois (tandis que KeyUp ne se déclenche qu'une seule fois lorsqu'il relâche le bouton). De plus, dans certains cas, vous pouvez facilement empêcher la propagation de KeyDown mais ne pouvez pas (ou ne pouvez pas le faire facilement) empêcher la propagation de KeyUp (par exemple, si vous souhaitez soumettre à l'entrée sans ajouter de nouvelle ligne au champ de texte).
  • Étonnamment, lorsque vous maintenez une clé, disons textarea, KeyPress et KeyDown se déclenchent plusieurs fois (Chrome 71), j'utiliserais KeyDown si j'ai besoin de l'événement qui se déclenche plusieurs fois et KeyUp pour la libération d'une seule clé.
  • KeyDown est généralement meilleur pour les jeux lorsque vous devez fournir une meilleure réactivité à leurs actions.
  • escest généralement traité via KeyDown: KeyPress ne se déclenche pas et KeyUp se comporte différemment pour inputs et textareas dans différents navigateurs (principalement en raison d'une perte de concentration)
  • Si vous souhaitez ajuster la hauteur d'une zone de texte au contenu, vous n'utiliserez probablement pas onKeyDown mais plutôt onKeyPress ( PS ok, il est en fait préférable d'utiliser onChange pour ce cas ).

J'ai utilisé les 3 dans mon projet, mais j'ai peut-être malheureusement oublié certains aspects pragmatiques. (à noter: il y a aussi inputet changeévénements)

YakovL
la source
Je n'avais pas pensé à keyup ajouter la nouvelle ligne au contenu du champ, mais c'est en fait important.
FKEinternet
10

Cet article de Jan Wolter est la meilleure pièce que j'ai rencontrée, vous pouvez trouver la copie archivée ici si le lien est mort.

Il explique très bien tous les événements clés du navigateur,

L' événement keydown se produit lorsque la touche est enfoncée, suivi immédiatement de l'événement keypress. Ensuite, l' événement keyup est généré lorsque la clé est relâchée.

Pour comprendre la différence entre les touches enfoncées et les touches , il est utile de faire la distinction entre les caractères et les touches . Une clé est un bouton physique sur le clavier de l'ordinateur. Un caractère est un symbole tapé en appuyant sur un bouton. Sur un clavier américain, frapper le4 appuyer touche tout en maintenant la Shifttouche enfoncée produit généralement un caractère "signe dollar". Ce n'est pas nécessairement le cas sur tous les claviers du monde. En théorie, la keydown et KeyUp événements représentent les touches enfoncée ou relâchée, tandis que l' pression de toucheévénement représente un caractère d' être tapé. Dans la pratique, ce n'est pas toujours ainsi que cela est mis en œuvre.

Pendant un certain temps, certains navigateurs ont déclenché un événement supplémentaire, appelé textInput , immédiatement après avoir appuyé sur la touche . Les premières versions de la norme DOM 3 envisageaient cela comme un remplacement pour l' événement de pression de touche , mais toute la notion a ensuite été révoquée. Webkit l'a pris en charge entre les versions 525 et 533, et on me dit qu'IE l'a pris en charge, mais je n'ai jamais détecté cela, probablement parce que Webkit exigeait qu'il soit appelé textInput tandis qu'IE l'a appelé textinput .

Il existe également un événement appelé entrée , pris en charge par tous les navigateurs, qui est déclenché juste après qu'une modification a été apportée à une zone de texte ou à un champ de saisie. En règle générale, une pression sur une touche se déclenche, puis le caractère tapé apparaît dans la zone de texte, puis l'entrée se déclenche. L' événement d' entrée ne donne en fait aucune information sur la clé qui a été tapée - vous devez inspecter la zone de texte pour comprendre ce qui a changé - nous ne le considérons donc pas vraiment comme un événement clé et ne le documentons pas vraiment ici . Bien qu'il ait été initialement défini uniquement pour les zones de texte et les zones de saisie, je pense qu'il y a un certain mouvement vers sa généralisation pour tirer également sur d'autres types d'objets.

Suraj Jain
la source
Meilleure réponse, alors comment obtenir, disons, le symbole du signe dollar à l'aide de la touche?
bluejayke
10

Il semble que onkeypress et onkeydown fassent de même (avec la petite différence de touches de raccourci déjà mentionnée ci-dessus).

Vous pouvez essayer ceci:

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

Et vous verrez que les événements onkeypress et onkeydown sont tous deux déclenchés lorsque la touche est enfoncée et non lorsque la touche est enfoncée.

La différence est que l'événement est déclenché non pas une fois mais plusieurs fois (tant que vous maintenez la touche enfoncée). Soyez conscient de cela et gérez-les en conséquence.

Falk
la source
Ctrl, Shift, CapsLock, Backspace et autres touches qui ne saisissent pas quelque chose ne provoquent pas d'keypress événement, mais déclenchent toujours un keydown.
CPHPython
8

L'événement onkeypress fonctionne pour toutes les clés sauf ALT, CTRL, SHIFT, ESC dans tous les navigateurs où l'événement onkeydown fonctionne pour toutes les clés. Signifie que l'événement onkeydown capture toutes les clés.

Mohd Sadiq
la source
keypress ignore également la suppression, les flèches, home / end, PgUp / PgDn, voir ma réponse pour plus de détails (vous pouvez également mettre à jour votre réponse)
YakovL
4

Je voulais juste partager une curiosité:

lorsque vous utilisez l'événement onkeydown pour activer une méthode JS, le code de caractère de cet événement n'est PAS le même que celui que vous obtenez avec onkeypress!

Par exemple, les touches du pavé numérique renverront les mêmes codes de caractères que les touches numériques au-dessus des touches alphabétiques lors de l'utilisation de onkeypress, mais PAS lors de l'utilisation de onkeydown!

Cela m'a pris quelques secondes pour comprendre pourquoi mon script qui vérifiait certains charcodes a échoué lors de l'utilisation de onkeydown!

Démo: https://www.w3schools.com/code/tryit.asp?filename=FMMBXKZLP1MK

et oui. Je sais que la définition des méthodes est différente .. mais ce qui est très déroutant, c'est que dans les deux méthodes, le résultat de l'événement est récupéré en utilisant event.keyCode .. mais ils ne renvoient pas la même valeur .. pas très mise en œuvre déclarative.

Le batteur
la source
Il semble que les choses soient les mêmes pour le caractère numérique ( 0123456789)
Mrigank Pawagi
Et avez-vous remarqué que keyDown donne la clé sur le clavier, tandis que keyPress donne le caractère exact que nous venons de taper (ou de cliquer)
Mrigank Pawagi
2

Fondamentalement, ces événements agissent différemment selon le type et la version du navigateur, j'ai créé un petit test jsBin et vous pouvez vérifier la console pour savoir comment ces événements se comportent pour votre environnement cible, espérons cette aide. http://jsbin.com/zipivadu/10/edit

Ken Chan
la source
1

Réponse mise à jour:

Touche Bas

  • Se déclenche plusieurs fois lorsque vous maintenez les touches enfoncées.
  • Déclenche une méta-clé.

Appuyez sur la touche

  • Se déclenche plusieurs fois lorsque vous maintenez les touches enfoncées.
  • Ne déclenche pas de méta-clés.

KeyUp

  • Se déclenche une fois à la fin lorsque vous relâchez la touche.
  • Déclenche une méta-clé.

C'est le comportement des deux addEventListeneret jQuery.

https://jsbin.com/vebaholamu/1/edit?js,console,output <- exemple d'essai

montre un exemple avec maintien de SSS

(la réponse a été modifiée avec la bonne réponse, capture d'écran et exemple)

Quang Van
la source
Sauf pour le keydown qui se déclenche plusieurs fois également
bluejayke
-1, car au moins un détail à ce sujet est incorrect dans au moins Chrome; comme le dit @bluejayke, KeyDown se déclenche également à plusieurs reprises lorsque vous maintenez une touche enfoncée.
Mark Amery
Ouais vous avez raison, désolé pour mon erreur; réponse modifiée.
Quang Van
0

Quelques faits pratiques qui pourraient être utiles pour décider de l'événement à gérer (exécutez le script ci-dessous et concentrez-vous sur la zone de saisie):

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

Pressage:

  • les touches non insérées / tapées (par exemple Shift, Ctrl) ne déclencheront pas a keypress. Appuyez Ctrlet relâchez:

    keydown 17 17 Contrôle

    keyup 17 17 Contrôle

  • les clés des claviers qui appliquent des transformations de caractères à d'autres caractères peuvent entraîner la mort et la duplication de "clés" (par exemple ~, ´) keydown. Appuyez ´et relâchez-le pour afficher un double ´´:

    keydown 192192 Dead

    keydown 192 192 ´´

    touche 180 180 ´

    touche 180 180 ´

    keyup 192192 Dead

De plus, les entrées ne tapant pas (par exemple, à distance <input type="range">) déclencheront toujours tous les événements de touches, de touches et de touches en fonction des touches enfoncées.

CPHPython
la source