.keyCode vs. .which


228

Pensé que esto sería respondido en algún lugar en Stack Overflow, pero no puedo encontrarlo.

Si estoy escuchando un evento de pulsación de tecla, ¿debería usar .keyCodeo .whichpara determinar si se presionó la tecla Intro?

Siempre he hecho algo como lo siguiente:

$("#someid").keypress(function(e) {
  if (e.keyCode === 13) {
    e.preventDefault();
    // do something
  }
});

Pero estoy viendo ejemplos que usan en .whichlugar de .keyCode. ¿Cual es la diferencia? ¿Es uno más compatible con todos los navegadores que el otro?


Respuestas:


209

Nota: a continuación La respuesta fue escrito en 2010. Aquí, muchos años después, tanto keyCodey whichse está desfasada y en key(para la clave lógica) y code(para la ubicación física de la llave). Pero tenga en cuenta que IE no es compatible code, y su compatibilidad keyse basa en una versión anterior de la especificación, por lo que no es del todo correcto. Mientras escribo esto, el Edge actual basado en EdgeHTML y Chakra tampoco es compatible code, pero Microsoft está implementando su reemplazo basado en Blink y V8 para Edge, que presumiblemente sí lo hará / lo hará.


Algunos navegadores usan keyCode, otros usan which.

Si está utilizando jQuery, puede utilizarlo de manera confiable whichya que jQuery estandariza las cosas ; Más aquí.

Si no está utilizando jQuery, puede hacer esto:

var key = 'which' in e ? e.which : e.keyCode;

O alternativamente:

var key = e.which || e.keyCode || 0;

... que maneja la posibilidad que e.whichpodría ser 0(al restaurar eso 0al final, usando el ||operador curiosamente poderoso de JavaScript ).


2
Gracias TJ ¿Dónde encontraría una referencia para esto? No es que no te crea, ¡solo tengo curiosidad! ... Veo que acabas de agregar eso, gracias. Entonces, incluso para aquellos que no usan jquery, ¿cuál es una mejor opción?
ScottE

77
@ScottE: si no usa jQuery, debe manejarlo explícitamente usted mismo. Usualmente lo hago así. var key = event.which || event.keyCode;Eso lo event.whichusaré event.keyCodesi whichestá definido y no es falso, o si no está definido o es falso. Técnicamente, probablemente debería hacer, var key = typeof event.which === "undefined" ? event.keyCode : event.which;pero si event.whiches así 0(¿puede ser 0?), Es poco probable que me importe el tipo de cosas que hago.
TJ Crowder

2
@ScottE, aquí hay una referencia básica: quirksmode.org/js/keys.html (no incluye which, que creo que solo es proporcionado por jQuery, pero no estoy 100% seguro, pero debería ayudarlo a comenzar a ver diferencias en los navegadores)
Mottie

1
@fudgey: whiches proporcionado keypresspor todos los navegadores, excepto IE. Y quirksmode no tiene autoridad aquí. Como referencia, el enlace que publicó @TJ Crowder es mucho mejor: unixpapa.com/js/key.html .
Tim Down

55
@TJ Crowder: Sí, la whichpropiedad del evento puede ser cero, y esto puede hacer una gran diferencia en la mayoría de las aplicaciones. Por ejemplo, las claves no imprimibles en Firefox tienen una whichpropiedad de cero y la misma keyCodepropiedad que keydown. La tecla Inicio tiene un keyCode36 en mi PC en Firefox, que es el código de caracteres para "$", lo que haría imposible distinguir entre el usuario que presiona la tecla Inicio y el usuario que escribe un carácter $ usando event.which || event.keyCode.
Tim Down

32

jQuery normaliza event.whichen función de si event.which, event.keyCodeo event.charCodeestá soportado por el navegador:

// Add which for key events
if ( event.which == null && (event.charCode != null || event.keyCode != null) ) {
   event.which = event.charCode != null ? event.charCode : event.keyCode;
}

Un beneficio adicional de .whichjQuery es que también lo hace para los clics del mouse:

// Add which for click: 1 === left; 2 === middle; 3 === right
// Note: button is not normalized, so don't use it
if ( !event.which && event.button !== undefined ) {
    event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
}

2
var key = event.which || event.charCode || event.keyCode
Anne van Rossum el

@ anne-van-rossum, event.wich == null && ...prueba solo para nulo o indefinido. su event.wich || ...prueba de falsedad (indefinido, nulo, falso, 0 '', etc.)
aMarCruz

@aMarCruz Falsy a propósito. Por ejemplo, bugs.webkit.org/show_bug.cgi?id=16735 con informes de Webkit 0. Y no creo que verifique ""o []duela.
Anne van Rossum

20

Si permanece en Javascript vainilla, tenga en cuenta que keyCode ahora está en desuso y se eliminará:

Esta característica se ha eliminado de los estándares web. Aunque algunos navegadores aún pueden soportarlo, está en proceso de ser eliminado. Evite usarlo y actualice el código existente si es posible; consulte la tabla de compatibilidad al final de esta página para guiar su decisión. Tenga en cuenta que esta característica puede dejar de funcionar en cualquier momento

https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode

En su lugar, use: .key o .code según el comportamiento que desee: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code https://developer.mozilla.org/en -US / docs / Web / API / KeyboardEvent / key

Ambos se implementan en navegadores modernos.


.code corresponde a la ubicación física de la tecla en el teclado, mientras que .key corresponde al carácter generado por la tecla presionada independientemente de la ubicación.
Christopher

1
Tanto el 'código' como la 'clave' tienen peculiaridades en los navegadores modernos. El uso del ejemplo "Pruébelo" en MDN developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code en diferentes navegadores muestra que IE11 / IE Edge no implementa 'código' y la 'clave' la implementación no coincide con la implementación en Chrome / FF / Safari (las diferencias parecen estar principalmente en los caracteres de control como Escape y Enter). Creo que usar una biblioteca podría ser más fácil a menos que esté dispuesto a dar cuenta de estos caprichos usted mismo. Realmente quiero que esta sea la respuesta, pero IE lo
arruina

Hmm ... en realidad no se ve tan mal implementar la clave en un navegador cruzado. Las teclas alfanuméricas normales solo devuelven su valor y para las teclas de control (escape, enter, tab, etc.) aparecen implementadas de manera idéntica en la mayoría de los navegadores, excepto IE11 / Edge que implementan una versión anterior de la especificación, por lo que al menos solo hay dos valores posibles para cada llave.
Akrikos

Aconsejaría usar en keylugar de code. Por ejemplo, si tiene un teclado con teclas de control de medios, al presionar Reproducir / Pausa sale "MediaPlayPause" para keyy "" para code.
Thdoan

6

mira esto: https://developer.mozilla.org/en-US/docs/Web/API/event.keyCode

En un evento de pulsación de tecla, el valor Unicode de la tecla presionada se almacena en la propiedad keyCode o charCode, nunca en ambas. Si la tecla presionada genera un carácter (por ejemplo, 'a'), charCode se establece en el código de ese carácter, respetando la letra mayúscula. (es decir, charCode tiene en cuenta si la tecla Mayús se mantiene presionada). De lo contrario, el código de la tecla presionada se almacena en keyCode. keyCode siempre se establece en los eventos keydown y keyup. En estos casos, charCode nunca se establece. Para obtener el código de la clave independientemente de si se almacenó en keyCode o charCode, consulte qué propiedad. Los caracteres ingresados ​​a través de un IME no se registran a través de keyCode o charCode.


6

Lo recomendaría event.keyactualmente. Documentos de MDN: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key

event.KeyCodey event.whichambos tienen advertencias desaprobadas desagradables en la parte superior de sus páginas MDN:
https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode https://developer.mozilla.org/en-US / docs / Web / API / KeyboardEvent / which

Para las claves alfanuméricas, event.keyparece implementarse de manera idéntica en todos los navegadores. Para las teclas de control (tab, enter, escape, etc.), event.keytiene el mismo valor en Chrome / FF / Safari / Opera pero un valor diferente en IE10 / 11 / Edge (los IE aparentemente usan una versión anterior de la especificación pero coinciden entre sí como del 14 de enero de 2018).

Para las teclas alfanuméricas, un cheque se vería así:

event.key === 'a'

Para los personajes de control, deberías hacer algo como:

event.key === 'Esc' || event.key === 'Escape'

Utilicé el ejemplo aquí para probar en varios navegadores (tuve que abrir en codepen y editar para que funcione con IE10): https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/ código

event.code se menciona en una respuesta diferente como una posibilidad, pero IE10 / 11 / Edge no lo implementa, por lo que está disponible si desea soporte de IE.


2

Una robusta biblioteca Javascript para capturar la entrada del teclado y las combinaciones de teclas ingresadas. No tiene dependencias.

http://jaywcjlove.github.io/hotkeys/

hotkeys('ctrl+a,ctrl+b,r,f', function(event,handler){
    switch(handler.key){
        case "ctrl+a":alert('you pressed ctrl+a!');break;
        case "ctrl+b":alert('you pressed ctrl+b!');break;
        case "r":alert('you pressed r!');break;
        case "f":alert('you pressed f!');break;
    }
});

teclas de acceso rápido comprende los siguientes modificadores: , shift, option, , alt, ctrl, control, command, y .

Las siguientes teclas especiales se pueden utilizar para los accesos directos: backspace, tab, clear, enter, return, esc, escape, space, up, down, left, right, home, end, pageup, pagedown, del, deletey f1a través f19.


Sin embargo, calza Array.prototype.indexOf, por lo que si está utilizando esto en otra biblioteca, puede no ser adecuado ya que modifica el alcance global. También parece usar el obsoleto event.keyCode.
Akrikos

Esta biblioteca no detectó Fn en mi computadora portátil Vaio.
Thdoan

0

En Firefox, la propiedad keyCode no funciona en el evento onkeypress (solo devolverá 0). Para una solución de navegador cruzado, use la propiedad which junto con keyCode, por ejemplo:

var x = event.which || event.keyCode;  // Use either which or keyCode, depending on browser support
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.