onKeyPress Vs. onKeyUp y onKeyDown

329

¿Cuál es la diferencia entre estos tres eventos? Al buscar en Google encontré que:

  • El onKeyDownevento se desencadena cuando el usuario presiona una tecla.
  • El onKeyUpevento se desencadena cuando el usuario suelta una clave.
  • El onKeyPressevento se activa cuando el usuario presiona y suelta una tecla ( onKeyDownseguida de onKeyUp).

Entiendo los dos primeros, pero ¿no es lo onKeyPressmismo que onKeyUp? ¿Es posible liberar una tecla ( onKeyUp) sin presionarla ( onKeyDown)?

Esto es un poco confuso, ¿alguien puede aclarar esto por mí?

instantsetsuna
fuente
3
Descubrí que si mantengo presionada la tecla TAB, se desplaza continuamente por todos los campos y solo activa 'onkeydown'.
nu everest
23
El evento de pulsación de tecla representa un carácter que se está escribiendo que se puede utilizar para la entrada, como 'a', 'D', '£', '©', etc. Por otro lado, los eventos keydown y keyup representan CUALQUIER tecla que se está escribiendo, que incluye elementos como retroceso, tabulación, arriba, abajo, inicio, fin, etc.
skcin7
2
"(¿o es posible liberar una tecla (KeyUp) sin presionar (KeyDown)?" - Sí. Por ejemplo, la tecla de tabulación: el evento keyup no puede ser capturado por el mismo elemento que el keydown.
Evidente

Respuestas:

191

Verifique aquí el enlace archivado utilizado originalmente en esta respuesta.

Desde ese enlace:

En teoría, los eventos onKeyDowny onKeyUprepresentan teclas que se presionan o sueltan, mientras que el onKeyPressevento representa un personaje que se está escribiendo. La implementación de la teoría no es la misma en todos los navegadores.

dcp
fuente
18
Arme un jsfiddle basado en la publicación de @ Falk para demostrar las idiosincrasias (usando jquery): jsfiddle.net/zG9MF/2
fordareh
No puedo ver la página vinculada, pero el punto sobre 'un carácter que se está escribiendo' es importante si planeas usar esto para cualquier tipo de validación. El evento de pulsación de tecla no se activa cuando el usuario elimina un carácter, por lo que su validación no se activará.
Tony Merryfield
@Tony Merryfield: el enlace funciona bien para mí, lo revisé nuevamente.
dcp
1
@dcp: Sí, fue una pista suficiente para llevarme por el camino correcto. Acabo de agregar mi comentario para reforzar el punto de que el evento solo se desencadena cuando se escribe un personaje en lugar de presionar cualquier tecla; obtuviste mi voto a favor;)
Tony Merryfield
1
Además, al presionar "una vez" una tecla, el evento KeyDown sigue disparando hasta que se suelta la tecla, en cuyo caso KeyUp se dispara solo una vez;)
Bernoulli IT
195

KeyPress, KeyUpY KeyDownson análogos a, respectivamente: Click, MouseUp,y MouseDown.

  1. Down sucede primero
  2. Press sucede en segundo lugar (cuando se ingresa el texto)
  3. Up sucede en último lugar (cuando se completa la entrada de texto).

La excepción es webkit , que tiene un evento adicional allí:

keydown
keypress
textInput     
keyup

A continuación hay un fragmento que puede usar para ver por sí mismo cuándo se desencadenan los eventos:

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

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

Robusto
fuente
1
Entonces, ¿KeyPress es solo un evento adicional que es b / w KeyDown y TextInput? ¿Cómo es (KeyPress) generalmente utilizado por los desarrolladores?
instantsetsuna
78
Mejor respuesta de +1: el * Abajo ocurre primero, la * Prensa pasa a segundo lugar (cuando se ingresa el texto), y el * Abajo ocurre el último (cuando se completa el ingreso de texto).
Scott Pelak
2
-1 porque un poco de experimentación en el fragmento contradice su analogía con el evento 'clic'. El evento 'clic' se dispara al mismo tiempo que 'mouseup' (cuando suelta el botón del mouse), pero el evento 'keypress' se dispara al mismo tiempo que 'keydown' (cuando se presiona la tecla por primera vez).
Mark Amery
2
@Robusto En realidad, a los eventos keypressy keydownliteralmente se les asigna el mismo .timeStampvalor, que es preciso a intervalos de 5 microsegundos, pero ese no es realmente mi punto de todos modos. Mi punto es que el clickevento no se dispara hasta que sueltas el botón del mouse, por lo que decir que keypresses la versión del teclado clickhace que suene como keypresstampoco se disparará hasta que sueltes la tecla. De hecho, ese no es el caso: se dispara cuando se presiona la tecla, al igual que lo keydownhace. Entonces, keypressde hecho, no es análogo a clicknada.
Mark Amery
2
@Robusto "¿cómo se explica la 'pulsación de tecla' siempre se está grabando después de la 'keydown'" - simple: la misma acción del usuario (empujando hacia abajo una llave) desencadena inmediatamente ambos manejadores de ser empujados a la cola de eventos, pero en un orden fijo . "solo quieres tener una discusión por el bien de la discusión" - ¿Eh? La tesis central de su respuesta es que keypress, keyupy keydownson análogos a click, mouseupy mousedown. La interpretación natural de eso, para mí, es que se keypressdispara en el mismo instante que keyup(al igual que clicky mouseup). Lo que hizo que quiere decir, si no que?
Mark Amery
23

La mayoría de las respuestas aquí se centran más en la teoría que en asuntos prácticos y hay algunas grandes diferencias entre keyupy keypressen lo que respecta a los valores de los campos de entrada, al menos en Firefox (probado en 43).

Si el usuario escribe 1en un elemento de entrada vacío:

  1. El valor del elemento de entrada será una cadena vacía (valor anterior) dentro del keypresscontrolador

  2. El valor del elemento de entrada será 1(nuevo valor) dentro del keyupcontrolador.

Esto es de importancia crítica si está haciendo algo que se basa en conocer el nuevo valor después de la entrada en lugar del valor actual, como la validación en línea o la tabulación automática.

Guión:

  1. El usuario escribe 12345en un elemento de entrada.
  2. El usuario selecciona el texto 12345.
  3. El usuario escribe la letra A.

Cuando el keypressevento se activa después de ingresar la letra A, el cuadro de texto ahora contiene solo la letra A.

Pero:

  1. Field.val () es 12345.
  2. $ Field.val (). Length es 5
  3. La selección de usuario es una cadena vacía (que le impide determinar qué se eliminó sobrescribiendo la selección).

Parece que el navegador (Firefox 43) borra la selección del usuario, luego dispara el keypressevento, luego actualiza el contenido de los campos y luego dispara keyup.

Mella
fuente
16

onkeydownse dispara cuando la tecla está presionada (como en los accesos directos; por ejemplo, en Ctrl+A, Ctrlse mantiene presionada.

onkeyup se dispara cuando se suelta la tecla (incluidas las teclas modificadoras / etc.)

onkeypressse dispara como una combinación de onkeydowny onkeyup, o dependiendo de la repetición del teclado (cuando onkeyupno se dispara). (Este comportamiento de repetición es algo que no he probado. ¡Si lo haces, agrega un comentario!)

textInput(solo webkit) se activa cuando se ingresa algún texto (por ejemplo, Shift+Aingresaría 'A' en mayúsculas, pero Ctrl+Aseleccionaría texto y no ingresaría ningún ingreso de texto. En ese caso, se activan todos los demás eventos)

arunjitsingh
fuente
1
Acabo de confirmar que, de hecho, "onkeypress" se llama repetidamente cuando se mantiene presionada la tecla y se produce "repetición del teclado". Sin embargo, esto también es cierto para "onkeydown". (que es inesperado, dado el nombre)
Venryx
11

Primero, tienen un significado diferente: disparan:

  • KeyDown: cuando se presionó una tecla
  • KeyUp: cuando se soltó un botón pulsado y después de actualizar el valor de input / textarea (el único entre estos)
  • KeyPress: entre esos y no significa que se haya presionado y liberado una tecla (ver más abajo).

En segundo lugar, algunas teclas activan algunos de estos eventos y no activan otros . Por ejemplo,

  • Ignora KeyPress delete, flechas, PgUp/ PgDn, home/ end, ctrl, alt, shiftetc, mientras que KeyDown y KeyUp no (ver detalles acerca de escmás abajo);
  • cuando cambia la ventana a través de alt+ taben Windows, solo KeyDown para altincendios se produce porque el cambio de ventana ocurre antes de cualquier otro evento (y supongo que KeyDown para tabes evitado por el sistema, al menos en Chrome 71).

Además, debe tener en cuenta que event.keyCode(y event.which) generalmente tienen el mismo valor para KeyDown y KeyUp pero diferente para KeyPress. Prueba el patio de recreo que he creado. Por cierto, he notado una peculiaridad: en Chrome, cuando presiono ctrl+ ay input/ textareaestá vacío, ¡para KeyPress se dispara con event.keyCode(y event.which) igual a 1! (cuando la entrada no está vacía, no se dispara en absoluto).

Finalmente, hay algunas pragmáticas :

  • Para manejar las flechas, probablemente necesitará usar onKeyDown: si el usuario mantiene presionado, KeyDown se dispara varias veces (mientras que KeyUp se dispara solo una vez cuando sueltan el botón). Además, en algunos casos puede evitar fácilmente la propagación de KeyDown pero no puede (o no puede hacerlo fácilmente) evitar la propagación de KeyUp (por ejemplo, si desea enviar al ingresar sin agregar nueva línea al campo de texto).
  • Sorprendentemente, cuando mantiene presionada una tecla, digamos textarea, tanto KeyPress como KeyDown se disparan varias veces (Chrome 71), usaría KeyDown si necesito el evento que se dispara varias veces y KeyUp para liberar una sola tecla.
  • KeyDown suele ser mejor para los juegos cuando tienes que proporcionar una mejor respuesta a sus acciones.
  • escpor lo general es procesada a través KeyDown: KeyPress no lo hace el fuego y KeyUp se comporta de forma diferente para inputs y textareaS en diferentes navegadores (sobre todo debido a la pérdida de concentración)
  • Si desea ajustar la altura de un área de texto al contenido, probablemente no usará onKeyDown sino onKeyPress ( PS ok, en realidad es mejor usar onChange para este caso ).

He usado los 3 en mi proyecto, pero desafortunadamente puede haber olvidado algo de pragmática. (a tener en cuenta: también hay inputy changeeventos)

YakovL
fuente
No había pensado en keyup agregando la nueva línea al contenido del campo, pero eso es realmente importante.
FKEinternet
10

Este artículo de Jan Wolter es la mejor pieza que he encontrado, puedes encontrar la copia archivada aquí si el enlace está muerto.

Explica todos los eventos clave del navegador realmente bien,

El evento keydown ocurre cuando se presiona la tecla, seguido inmediatamente por el evento de presionar la tecla. Luego, el evento keyup se genera cuando se libera la clave.

Para comprender la diferencia entre presionar tecla y presionar tecla , es útil distinguir entre caracteres y teclas . Una tecla es un botón físico en el teclado de la computadora. Un personaje es un símbolo escrito presionando un botón. En un teclado estadounidense, 4presionar la tecla mientras se mantiene presionada la Shifttecla normalmente produce un carácter de "signo de dólar". Este no es necesariamente el caso en todos los teclados del mundo. En teoría, los eventos keydown y keyup representan teclas presionadas o liberadas, mientras que la tecla presionadaEl evento representa un carácter que se está escribiendo. En la práctica, esta no siempre es la forma en que se implementa.

Durante un tiempo, algunos navegadores activaron un evento adicional, llamado textInput , inmediatamente después de presionar una tecla . Las primeras versiones del estándar DOM 3 pretendían esto como un reemplazo para el evento de pulsación de tecla , pero la noción completa fue revocada más tarde. Webkit admitió esto entre las versiones 525 y 533, y me dijeron que IE lo admitió , pero nunca lo detecté, posiblemente porque Webkit requirió que se llamara textInput mientras que IE lo llamó textinput .

También hay un evento llamado input , compatible con todos los navegadores, que se activa justo después de realizar un cambio en un área de texto o campo de entrada. Por lo general, la pulsación de tecla se activará, luego el carácter escrito aparecerá en el área de texto, luego se activará la entrada. El evento de entrada en realidad no brinda ninguna información sobre qué tecla se ingresó; tendría que inspeccionar el cuadro de texto para averiguar qué cambió, por lo que realmente no lo consideramos un evento clave y realmente no lo documentamos aquí . Aunque originalmente se definió solo para áreas de texto y cuadros de entrada, creo que también hay algún movimiento hacia la generalización para disparar a otros tipos de objetos.

Suraj Jain
fuente
La mejor respuesta, entonces, ¿cómo puede obtener, digamos, el símbolo del signo de dólar al presionar una tecla?
bluejayke
10

Parece que onkeypress y onkeydown hacen lo mismo (dentro de la pequeña diferencia de teclas de acceso directo ya mencionadas anteriormente).

Puedes probar esto:

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

Y verá que los eventos al presionar la tecla y al presionar la tecla se activan mientras se presiona la tecla y no cuando se presiona la tecla.

La diferencia es que el evento se desencadena no una, sino muchas veces (siempre que mantenga presionada la tecla). Tenga en cuenta eso y manejarlos en consecuencia.

Falk
fuente
Ctrl, Shift, CapsLock, Retroceso y otras teclas que nokeypress escriben algo no causan un evento, pero siempre desencadenan un keydown.
CPHPython
8

El evento onkeypress funciona para todas las teclas excepto ALT, CTRL, SHIFT, ESC en todos los navegadores donde el evento onkeydown funciona para todas las teclas. Significa que el evento onkeydown captura todas las claves.

Mohd Sadiq
fuente
la pulsación de tecla también ignora eliminar, flechas, inicio / fin, PgUp / PgDn, vea mi respuesta para más detalles (es posible que también desee actualizar su respuesta)
YakovL
4

Solo quería compartir una curiosidad:

cuando se usa el evento onkeydown para activar un método JS, ¡el código de acceso para ese evento NO es el mismo que se obtiene con onkeypress!

Por ejemplo, las teclas del teclado numérico devolverán los mismos códigos de caracteres que las teclas numéricas sobre las teclas de letras cuando se usa onkeypress, ¡pero NO cuando se usa onkeydown!

¡Me tomó unos segundos descubrir por qué mi script que verificó ciertos códigos de barras falló al usar onkeydown!

Demostración: https://www.w3schools.com/code/tryit.asp?filename=FMMBXKZLP1MK

y si. Sé que la definición de los métodos es diferente ... pero lo que es muy confuso es que en ambos métodos el resultado del evento se recupera usando event.keyCode ... pero no devuelven el mismo valor ... no es muy Implementación declarativa.

Batería
fuente
Parece que las cosas son iguales para Numeric Character ( 0123456789)
Mrigank Pawagi
¿Y notó que keyDown le da la CLAVE en el teclado, mientras que keyPress le da el carácter exacto que acabamos de escribir (o
cliqueamos
2

Básicamente, estos eventos actúan de manera diferente en diferentes tipos y versiones de navegadores, creé una pequeña prueba jsBin y puede consultar la consola para averiguar cómo se comportan estos eventos para su entorno objetivo, espero esta ayuda. http://jsbin.com/zipivadu/10/edit

Ken Chan
fuente
1

Respuesta actualizada:

KeyDown

  • Se dispara varias veces cuando mantiene presionadas las teclas.
  • Dispara meta key.

KeyPress

  • Se dispara varias veces cuando mantiene presionadas las teclas.
  • No no disparar teclas meta.

Tecla Arriba

  • Se dispara una vez al final cuando sueltas la tecla.
  • Dispara meta key.

Este es el comportamiento en ambos addEventListenery jQuery.

https://jsbin.com/vebaholamu/1/edit?js,console,output <- prueba ejemplo

muestra un ejemplo al mantener presionado SSS

(la respuesta ha sido editada con la respuesta correcta, captura de pantalla y ejemplo)

Quang Van
fuente
A excepción de keydown que dispara varias veces también
bluejayke
-1, porque al menos un detalle sobre esto es incorrecto en al menos Chrome; Como dice @bluejayke, KeyDown también se activa repetidamente cuando mantiene presionada una tecla.
Mark Amery
Sí, ustedes tienen razón, perdón por mi error; respuesta editada
Quang Van
0

Algunos datos prácticos que pueden ser útiles para decidir qué evento manejar (ejecute el script a continuación y concéntrese en el cuadro de entrada):

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

Prensado:

  • las teclas que no se insertan / escriben (p Shift. ej . Ctrl) no activarán a keypress. Presione Ctrly suelte:

    keydown 17 17 Control

    tecla 17 17 Control

  • Las teclas de los teclados que aplican transformaciones de caracteres a otros caracteres pueden conducir a "teclas" muertas y duplicadas (por ejemplo ~, ´) en keydown. Presiónelo ´y suéltelo para mostrar un doble ´´:

    keydown 192 192 Dead

    keydown 192 192 ´´

    pulsación de tecla 180 180 ´

    pulsación de tecla 180 180 ´

    keyup 192 192 Dead

Además, las entradas que no se escriben (por ejemplo, a distancia <input type="range">) seguirán activando todos los eventos de pulsación de tecla, pulsación de tecla y pulsación de tecla de acuerdo con las teclas presionadas.

CPHPython
fuente