
📋 Códigos de teclas de JavaScript: tabla completa de event.key, event.code y event.which
Un usuario presiona Escape y el modal no se cierra. Pulsa Enter en el campo de búsqueda y no ocurre nada. ¿Le suena familiar? El manejo del teclado en JavaScript parece sencillo hasta que empieza a lidiar con tres eventos, una docena de propiedades y un zoológico de diferencias entre navegadores.
Cada keydown o keyup genera un objeto KeyboardEvent con dos docenas de campos. Algunos están obsoletos desde la época de IE, otros se comportan distinto en Firefox y Chrome. Y la documentación de MDN está plagada de notas de «no usar». Los desarrolladores no necesitan otra especificación, necesitan una hoja de referencia que funcione.
A continuación encontrará una referencia completa sobre eventos de teclado: desde la anatomía de KeyboardEvent hasta fragmentos listos para usar en atajos de teclado. Guarde la tabla de códigos en marcadores, la necesitará en prácticamente cada proyecto.
💡 Resumen rápido:
- Use
keydownen lugar dekeypress: funciona para cualquier tecla. event.keydevuelve el símbolo de la tecla,event.codedevuelve su código físico.event.keyCodeyevent.whichestán obsoletos, no los use en código nuevo.- La tabla siguiente recopila los códigos de todas las teclas estándar en los navegadores modernos.
Qué contiene KeyboardEvent
Cuando un usuario presiona cualquier tecla, el navegador crea un objeto KeyboardEvent, descendiente de UIEvent, que a su vez extiende el Event base. Dentro están las propiedades de la tecla, el estado de los modificadores y la información de la distribución del teclado.

La especificación de UI Events está evolucionando: aparecen propiedades nuevas y las antiguas pasan a estar obsoletas. El cambio principal de los últimos años es el abandono de los códigos numéricos (keyCode / charCode / which) en favor de event.key y event.code. Todos los navegadores modernos admiten este par, y debería construir su lógica sobre ellos.
El soporte de los navegadores es prácticamente completo: Chrome 51+, Firefox 29+, Safari 10.1+, Edge 79+. Si su proyecto no está anclado a IE11, puede olvidarse de event.which.
Tres eventos: keydown, keypress y keyup
El navegador distingue tres eventos de teclado. El orden de ejecución es fijo:
- keydown, la tecla se presiona (momento del contacto);
- keypress, la tecla se mantiene y genera un carácter (solo para teclas de carácter);
- keyup, la tecla se suelta.
Suscripción a keydown mediante addEventListener:
1 const input = document.getElementById('type-here'); 2 3 input.addEventListener('keydown', function (event) { 4 console.log('Нажата:', event.key, '| Код:', event.code); 5 });
Para manejadores en línea, use un atributo del elemento:
1 <input type="text" id="type-here" onkeyup="handleKey(event)">
Si imprime el objeto evento en la consola, verá la estructura completa con todos los campos heredados de UIEvent y Event:

Por qué keydown es la opción principal
keypress está oficialmente reconocido como obsoleto. Solo se dispara para teclas que producen un valor de carácter y no captura modificadores: ni Alt, ni Ctrl, ni Shift, ni Meta. No puede manejar Ctrl+Z ni Shift+Tab mediante keypress.
La diferencia entre keydown y keyup: keydown se dispara antes de que el navegador procese la tecla; keyup se dispara después. De esto se deriva una consecuencia importante: event.preventDefault() dentro de keydown cancela la acción del navegador (por ejemplo, introducir un carácter en un campo), pero dentro de keyup no lo hace. Para atajos de teclado, validación de entrada y controles de juegos, necesita keydown.
Tabla de propiedades de KeyboardEvent
Propiedad / Método | Qué devuelve | Estado |
|---|---|---|
| Valor del carácter de la tecla presionada: | Vigente |
| Código físico de la tecla en el teclado: | Vigente |
|
| Vigente |
|
| Vigente |
|
| Vigente |
|
| Vigente |
|
| Vigente |
| Código numérico de la tecla (por ejemplo | Obsoleto |
| Código Unicode del carácter | Obsoleto |
| Código numérico de la tecla (análogo a | Obsoleto |
Las tres últimas filas están obsoletas. Siempre que sea posible, migre a event.key. Si tiene que dar soporte a un navegador antiguo, implemente un fallback:
1 window.addEventListener('keydown', function (event) { 2 const key = event.key !== undefined ? event.key : event.which; 3 if (key !== undefined) { 4 console.log('Клавиша:', key); 5 } 6 });
Pero en 2026, ese código es solo para proyectos heredados. event.key funciona en todas partes.
Teclas modificadoras y combinaciones
Las teclas Control, Shift, Alt y Meta no realizan acciones por sí solas, pero cambian el comportamiento de otras teclas. Presionar Z da la letra «z», mientras que Ctrl+Z ejecuta deshacer.
Las propiedades booleanas del evento ayudan a rastrear un modificador:
1 document.getElementById('editor').addEventListener('keydown', function (event) { 2 if (event.ctrlKey && event.key === 'z') { 3 event.preventDefault(); 4 undoAction(); 5 } 6 7 if (event.ctrlKey && event.shiftKey && event.key === 'z') { 8 event.preventDefault(); 9 redoAction(); 10 } 11 });
El mismo enfoque se aplica a cualquier combinación: Ctrl+S (guardar), Ctrl+Shift+N (nueva ventana), Alt+Tab (cambiar). Verifique el orden: primero los modificadores mediante banderas booleanas, luego event.key para la tecla específica. Esto hace que la lógica sea legible en lugar de ahogarse en códigos numéricos.
Tabla completa de códigos de teclas
A continuación se muestra la tabla vigente para todas las teclas estándar. Los valores event.key y event.code se presentan tal como los devuelven los navegadores modernos (Chrome, Firefox, Edge, Safari).
Navegación y acciones
Tecla | event.which | event.key | event.code | Nota |
|---|---|---|---|---|
Backspace | 8 | Backspace | Backspace |
|
Tab | 9 | Tab | Tab |
|
Enter | 13 | Enter | Enter |
|
Shift (izquierda) | 16 | Shift | ShiftLeft |
|
Shift (derecha) | 16 | Shift | ShiftRight |
|
Ctrl (izquierda) | 17 | Control | ControlLeft |
|
Ctrl (derecha) | 17 | Control | ControlRight |
|
Alt (izquierda) | 18 | Alt | AltLeft |
|
Alt (derecha) | 18 | Alt | AltRight |
|
Pause / Break | 19 | Pause | Pause |
|
Caps Lock | 20 | CapsLock | CapsLock |
|
Escape | 27 | Escape | Escape |
|
Espacio | 32 |
| Space |
|
Page Up | 33 | PageUp | PageUp |
|
Page Down | 34 | PageDown | PageDown |
|
End | 35 | End | End |
|
Home | 36 | Home | Home |
|
Flecha izquierda | 37 | ArrowLeft | ArrowLeft |
|
Flecha arriba | 38 | ArrowUp | ArrowUp |
|
Flecha derecha | 39 | ArrowRight | ArrowRight |
|
Flecha abajo | 40 | ArrowDown | ArrowDown |
|
Print Screen | 44 | PrintScreen | PrintScreen |
|
Insert | 45 | Insert | Insert |
|
Delete | 46 | Delete | Delete |
|
Fila numérica (teclado principal)
Tecla | event.which | event.key | event.code |
|---|---|---|---|
0 | 48 | 0 | Digit0 |
1 | 49 | 1 | Digit1 |
2 | 50 | 2 | Digit2 |
3 | 51 | 3 | Digit3 |
4 | 52 | 4 | Digit4 |
5 | 53 | 5 | Digit5 |
6 | 54 | 6 | Digit6 |
7 | 55 | 7 | Digit7 |
8 | 56 | 8 | Digit8 |
9 | 57 | 9 | Digit9 |
Letras A-Z
Tecla | event.which | event.key | event.code |
|---|---|---|---|
A | 65 | a | KeyA |
B | 66 | b | KeyB |
C | 67 | c | KeyC |
D | 68 | d | KeyD |
E | 69 | e | KeyE |
F | 70 | f | KeyF |
G | 71 | g | KeyG |
H | 72 | h | KeyH |
I | 73 | i | KeyI |
J | 74 | j | KeyJ |
K | 75 | k | KeyK |
L | 76 | l | KeyL |
M | 77 | m | KeyM |
N | 78 | n | KeyN |
O | 79 | o | KeyO |
P | 80 | p | KeyP |
Q | 81 | q | KeyQ |
R | 82 | r | KeyR |
S | 83 | s | KeyS |
T | 84 | t | KeyT |
U | 85 | u | KeyU |
V | 86 | v | KeyV |
W | 87 | w | KeyW |
X | 88 | x | KeyX |
Y | 89 | y | KeyY |
Z | 90 | z | KeyZ |
event.key devuelve el valor en minúscula para las letras. event.code no depende de mayúsculas ni de la distribución del teclado: KeyA significa la tecla física A, incluso si la distribución es rusa y la entrada es «Ф».
Teclas especiales
Tecla | event.which | event.key | event.code | Nota |
|---|---|---|---|---|
Windows izquierda | 91 | Meta | MetaLeft |
|
Windows derecha | 92 | Meta | MetaRight |
|
Menú contextual | 93 | ContextMenu | ContextMenu |
|
Teclado numérico (Numpad)
Tecla | event.which | event.key | event.code |
|---|---|---|---|
Numpad 0 | 96 | 0 | Numpad0 |
Numpad 1 | 97 | 1 | Numpad1 |
Numpad 2 | 98 | 2 | Numpad2 |
Numpad 3 | 99 | 3 | Numpad3 |
Numpad 4 | 100 | 4 | Numpad4 |
Numpad 5 | 101 | 5 | Numpad5 |
Numpad 6 | 102 | 6 | Numpad6 |
Numpad 7 | 103 | 7 | Numpad7 |
Numpad 8 | 104 | 8 | Numpad8 |
Numpad 9 | 105 | 9 | Numpad9 |
Numpad Multiplicar | 106 | * | NumpadMultiply |
Numpad Sumar | 107 | + | NumpadAdd |
Numpad Restar | 109 | - | NumpadSubtract |
Numpad Decimal | 110 | . | NumpadDecimal |
Numpad Dividir | 111 | / | NumpadDivide |
Teclas de función
Tecla | event.which | event.key | event.code |
|---|---|---|---|
F1 | 112 | F1 | F1 |
F2 | 113 | F2 | F2 |
F3 | 114 | F3 | F3 |
F4 | 115 | F4 | F4 |
F5 | 116 | F5 | F5 |
F6 | 117 | F6 | F6 |
F7 | 118 | F7 | F7 |
F8 | 119 | F8 | F8 |
F9 | 120 | F9 | F9 |
F10 | 121 | F10 | F10 |
F11 | 122 | F11 | F11 |
F12 | 123 | F12 | F12 |
Sistema y multimedia
Tecla | event.which | event.key | event.code | Nota |
|---|---|---|---|---|
Num Lock | 144 | NumLock | NumLock |
|
Scroll Lock | 145 | ScrollLock | ScrollLock |
|
Silencio | 173 | AudioVolumeMute | AudioVolumeMute | En Firefox |
Bajar volumen | 174 | AudioVolumeDown | AudioVolumeDown | En Firefox |
Subir volumen | 175 | AudioVolumeUp | AudioVolumeUp | En Firefox |
Reproductor multimedia | 181 | LaunchMediaPlayer | LaunchMediaPlayer | En Firefox |
Lanzar App 1 | 182 | LaunchApplication1 | LaunchApplication1 | En Firefox |
Lanzar App 2 | 183 | LaunchApplication2 | LaunchApplication2 | En Firefox |
Puntuación y símbolos
Tecla | event.which | event.key | event.code | Nota |
|---|---|---|---|---|
Punto y coma (;) | 186 | ; | Semicolon | En Firefox |
Igual (=) | 187 | = | Equal | En Firefox |
Coma ( | 188 |
| Comma |
|
Menos (-) | 189 | - | Minus | En Firefox |
Punto (.) | 190 | . | Period |
|
Barra (/) | 191 | / | Slash |
|
Acento grave ( | Backquote |
|
|
|
Corchete izquierdo ([) | 219 | [ | BracketLeft |
|
Barra invertida () | 220 | \ | Backslash |
|
Corchete derecho (]) | 221 | ] | BracketRight |
|
Comilla simple (') | 222 | ' | Quote |
|
Notas importantes de la tabla
event.whiches una propiedad obsoleta, useevent.key.event.codees idéntico para letras minúsculas (a) y mayúsculas (A), es la tecla física.event.keydevuelve el carácter real considerando mayúsculas y minúsculas.- En Firefox, los valores de
event.whichpara las teclasEqual,SemicolonyMinusdifieren de Chrome/Edge/Safari (anotado en la tabla). Otra razón para no usarevent.which. - Los navegadores basados en Chromium y Firefox dan valores idénticos de
event.keyyevent.codepara todas las teclas listadas. - Teclados virtuales: la especificación de UI Events exige que un teclado virtual (móvil, en pantalla) que repita una distribución estándar devuelva el
event.codecorrecto. En la práctica, los navegadores móviles (Chrome Android, Safari iOS) manejan correctamentekeydown/keyuppara las teclas principales, peroevent.codepuede estar vacío para distribuciones no estándar.
Entrenador interactivo

Para una verificación rápida de cualquier código del artículo, use el entrenador de teclado: keyevents.netlify.app. Mueva el cursor al área, presione teclas y vea los valores de event.key, event.code y event.which, así como los estados de las banderas de modificadores en tiempo real. El código fuente está disponible en GitHub.
Video: eventos de teclado en la práctica
Un breve desglose práctico de keydown y keyup, trabajo con modificadores y atajos de teclado con ejemplos en vivo:
⁉️🤔 Preguntas frecuentes
¿Cuál es la diferencia entre event.key y event.code?
event.keydevuelve el valor del carácter considerando la distribución y las mayúsculas: para la tecla A es"a"(o"A"con Shift), para la distribución rusa,"ф".event.codedevuelve el código físico de la tecla, idéntico para todas las distribuciones:"KeyA". Para atajos de teclado,event.codees más fiable, no depende del idioma de entrada. Para entrada de texto, useevent.key.
¿Por qué ya no se usa keypress?
La especificación del W3C marcó
keypresscomo obsoleto: solo se dispara para teclas de carácter y no captura modificadores. No puede manejarCtrl+C,Shift+Taby otras combinaciones mediantekeypress.keydowncubre todas las teclas y tiene un soporte idéntico en todos los navegadores modernos.
¿Se puede abandonar por completo event.which y event.keyCode?
Sí, en 2026 puede hacerlo.
event.keyes compatible con Chrome 51+, Firefox 29+, Safari 10.1+, Edge 79+. Si su proyecto no apunta a IE11 ni a Firefox 28, use soloevent.keyyevent.code.
¿Cómo se maneja una pulsación larga de tecla?
Combine
keydownykeyup. Enkeydowninicie un temporizador orequestAnimationFrame, enkeyup, reinícielo. Para entrada de juegos, este es el patrón estándar: tecla mantenida, personaje se mueve; soltada, se detiene.
¿Funcionan los eventos de teclado en dispositivos móviles?
keydownykeyupfuncionan en navegadores móviles al usar un teclado Bluetooth externo. El teclado en pantalla genera eventosinput, nokeydown/keyuppara todas las teclas, por lo que para campos de texto en móviles es mejor usar el eventoinput.
¿Cómo se distingue Shift izquierda de la derecha?
Mediante
event.code:"ShiftLeft"o"ShiftRight".event.keydevuelve"Shift"para ambas. Lo mismo paraControl,AltyMeta.
Qué usar en su proyecto
Si está escribiendo código nuevo, tome keydown como evento principal y, para la identificación de teclas, event.key (símbolo) y event.code (tecla física). Esta combinación cubre todos los escenarios: atajos de teclado, navegación, entrada de juegos, validación de formularios.
Si mantiene un producto con código heredado basado en event.which o event.keyCode, planifique una refactorización. El volumen de trabajo es pequeño: reemplazo en los manejadores, pero el beneficio es un código limpio y predecible sin un zoológico de diferencias entre navegadores.
Guarde la tabla anterior en marcadores. La próxima vez que necesite el código de una tecla específica, ábrala y copie el valor event.code necesario sin tener que recordar códigos numéricos de la era de IE6.



