.keyCode vs. .which

228

Je pensais que ce serait répondu quelque part sur Stack Overflow, mais je ne le trouve pas.

Si j'écoute un événement de pression de touche, dois-je utiliser .keyCodeou .whichpour déterminer si la touche Entrée a été enfoncée?

J'ai toujours fait quelque chose comme ceci:

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

Mais je vois des exemples qui utilisent .whichau lieu de .keyCode. Quelle est la différence? Un navigateur est-il plus convivial que l'autre?

ScottE
la source
1
Ces deux éléments sont considérés comme obsolètes maintenant, pour info. developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/which developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode
CodeFinity

Réponses:

209

Remarque: La réponse ci-dessous a été écrite en 2010. Ici plusieurs années plus tard, les deux keyCodeet whichsont déconseillés en faveur de key(pour la clé logique) et code(pour le placement physique de la clé). Mais notez qu'IE ne prend pas en charge codeet que sa prise en charge keyest basée sur une ancienne version de la spécification, elle n'est donc pas tout à fait correcte. Au moment où j'écris ceci, l'Edge actuel basé sur EdgeHTML et Chakra ne prend pas en charge non codeplus, mais Microsoft déploie son remplacement basé sur Blink et V8 pour Edge, ce qui est probablement le cas / le sera.


Certains navigateurs utilisent keyCode, d'autres utilisent which.

Si vous utilisez jQuery, vous pouvez l'utiliser de manière fiable whichcar jQuery normalise les choses ; Plus ici.

Si vous n'utilisez pas jQuery, vous pouvez le faire:

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

Ou bien:

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

... qui gère la possibilité qui e.whichpourrait se présenter 0(en restaurant cela 0à la fin, en utilisant l' ||opérateur curieusement puissant de JavaScript ).

TJ Crowder
la source
2
Merci TJ Où pourrais-je trouver une référence pour cela? Non pas que je ne te crois pas, je suis juste curieux! ... Je vois que vous venez d'ajouter cela, merci. Donc, même pour ceux qui n'utilisent pas jquery, .qui est un meilleur choix?
ScottE
7
@ScottE: Si vous n'utilisez pas jQuery, vous devez gérer cela explicitement vous-même. Je le fais habituellement comme ça. var key = event.which || event.keyCode;Cela utilisera event.whichs'il est défini et non falsey, ou event.keyCodes'il whichest indéfini ou falsey. Techniquement, je devrais probablement le faire, var key = typeof event.which === "undefined" ? event.keyCode : event.which;mais si event.whichc'est le cas 0(est-ce possible 0?), Il est peu probable que je prenne soin du genre de choses que je fais.
TJ Crowder du
2
@ScottE, voici une référence de base: quirksmode.org/js/keys.html (il ne comprend pas which, qui je pense n'est fourni que par jQuery mais je ne suis pas sûr à 100%, mais cela devrait vous aider à commencer à voir différences dans les navigateurs)
Mottie
1
@fudgey: whichest fourni keypresspar tous les navigateurs sauf IE. Et le quirksmode ne fait pas autorité ici. À titre de référence, le lien publié par @TJ Crowder est bien meilleur: unixpapa.com/js/key.html .
Tim Down du
5
@TJ Crowder: Oui, la whichpropriété de l'événement peut être nulle, ce qui peut faire une grande différence pour la plupart des applications. Par exemple, les clés non imprimables dans Firefox ont une whichpropriété de zéro et la même keyCodepropriété que keydown. La touche Accueil a un keyCode36 sur mon PC dans Firefox, qui est le code de caractère pour "$", ce qui rendrait impossible de faire la distinction entre l'utilisateur appuyant sur la touche Accueil et l'utilisateur tapant un caractère $ en utilisant event.which || event.keyCode.
Tim Down du
32

jQuery normalisera event.whichselon que event.which, event.keyCodeou event.charCodeest pris en charge par le navigateur:

// 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 avantage supplémentaire de .whichest que jQuery le fait aussi pour les clics de souris:

// 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 ) ));
}
David Tang
la source
2
var key = event.which || event.charCode || event.keyCode
Anne van Rossum
@ anne-van-rossum, event.wich == null && ...test pour null ou indéfini uniquement. votre event.wich || ...test de falsification (indéfini, nul, faux, 0, '', etc.)
aMarCruz
@aMarCruz Falsy exprès. Par exemple, bugs.webkit.org/show_bug.cgi?id=16735 avec les rapports Webkit 0. Et je ne pense pas que vérifier ""ou faire []mal.
Anne van Rossum
20

Si vous séjournez dans vanilla Javascript, veuillez noter que keyCode est désormais obsolète et sera supprimé:

Cette fonctionnalité a été supprimée des normes Web. Bien que certains navigateurs puissent toujours le prendre en charge, il est en cours de suppression. Évitez de l'utiliser et mettez à jour le code existant si possible; consultez le tableau de compatibilité au bas de cette page pour guider votre décision. Sachez que cette fonctionnalité peut cesser de fonctionner à tout moment

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

Utilisez plutôt: .key ou .code selon le comportement que vous souhaitez: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code https://developer.mozilla.org/en -US / docs / Web / API / KeyboardEvent / key

Les deux sont implémentés sur des navigateurs modernes.

slykat
la source
.code correspond à l'emplacement physique de la touche sur le clavier tandis que .key correspond au caractère généré par la touche enfoncée quel que soit l'emplacement.
Christopher
1
Le «code» et la «clé» ont tous deux des bizarreries dans les navigateurs modernes. L'utilisation de l'exemple "Try it out" sur MDN developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code dans différents navigateurs montre qu'IE11 / IE Edge n'implémentent pas le 'code' et la 'clé' l'implémentation ne correspond pas à l'implémentation dans Chrome / FF / Safari (les différences semblent être principalement dans les caractères de contrôle comme Escape et Enter). Je pense que l'utilisation d'une bibliothèque pourrait être plus facile, sauf si vous êtes prêt à expliquer vous-même ces caprices. Je veux vraiment que ce soit la réponse, mais IE
bouscule
Hmm ... en fait, cela ne semble pas trop mal d'implémenter la clé de manière croisée. Les clés alphanumériques normales renvoient simplement leur valeur et pour les touches de contrôle (échapper, entrer, tabuler, etc.) apparaissent implémentées de manière identique dans la plupart des navigateurs, à l'exception d'IE11 / Edge qui implémentent une ancienne version de la spécification, il n'y a donc au moins que deux valeurs possibles pour chaque clé.
Akrikos
Je conseillerais d'utiliser keyau lieu de code. Par exemple, si vous avez un clavier avec des touches de contrôle multimédia, appuyez sur Lecture / Pause pour afficher "MediaPlayPause" pour keyet "" pour code.
thdoan
6

regardez ceci: https://developer.mozilla.org/en-US/docs/Web/API/event.keyCode

Dans un événement de pression de touche, la valeur Unicode de la touche enfoncée est stockée dans la propriété keyCode ou charCode, jamais les deux. Si la touche enfoncée génère un caractère (par exemple «a»), charCode est défini sur le code de ce caractère, en respectant la casse des lettres. (c'est-à-dire que charCode prend en compte si la touche Maj est maintenue enfoncée). Sinon, le code de la touche enfoncée est stocké dans keyCode. keyCode est toujours défini dans les événements keydown et keyup. Dans ces cas, charCode n'est jamais défini. Pour obtenir le code de la clé, qu'elle ait été stockée dans keyCode ou charCode, interrogez la propriété which. Les caractères entrés via un IME ne s'enregistrent pas via keyCode ou charCode.

Leo
la source
6

Je recommanderais event.keyactuellement. Documents MDN: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key

event.KeyCodeet les event.whichdeux ont des avertissements désapprouvés désagréables en haut de leurs pages MDN:
https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode https://developer.mozilla.org/en-US / docs / Web / API / KeyboardEvent / qui

Pour les clés alphanumériques, event.keysemble être implémenté de manière identique dans tous les navigateurs. Pour les touches de contrôle (tab, enter, escape, etc.), event.keya la même valeur dans Chrome / FF / Safari / Opera mais une valeur différente dans IE10 / 11 / Edge (les IE utilisent apparemment une version plus ancienne de la spécification mais se correspondent comme du 14 janvier 2018).

Pour les clés alphanumériques, un chèque ressemblerait à quelque chose comme:

event.key === 'a'

Pour les personnages de contrôle, vous devez faire quelque chose comme:

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

J'ai utilisé l'exemple ici pour tester sur plusieurs navigateurs (j'ai dû ouvrir dans codepen et modifier pour le faire fonctionner avec IE10): https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/ code

event.code est mentionné dans une réponse différente comme une possibilité, mais IE10 / 11 / Edge ne l'implémente pas, il est donc désactivé si vous souhaitez une prise en charge IE.

Akrikos
la source
2

Une bibliothèque Javascript robuste pour capturer les saisies au clavier et les combinaisons de touches saisies. Il n'a pas de dépendances.

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;
    }
});

raccourcis clavier comprend les modificateurs suivants: , shift, option, , alt, ctrl, control, command, et .

Les touches spéciales suivantes peuvent être utilisées pour les raccourcis: backspace, tab, clear, enter, return, esc, escape, space, up, down, left, right, home, end, pageup, pagedown, del, deleteet à f1travers f19.

小弟 调 调
la source
Cependant, il shim Array.prototype.indexOf, donc si vous l'utilisez dans une autre bibliothèque, il peut ne pas convenir car il modifie la portée globale. Il semble également utiliser le déprécié event.keyCode.
Akrikos
Cette bibliothèque n'a pas détecté Fn sur mon ordinateur portable Vaio.
thdoan
0

Dans Firefox, la propriété keyCode ne fonctionne pas sur l'événement onkeypress (ne renverra que 0). Pour une solution multi-navigateur, utilisez la propriété which avec keyCode, par exemple:

var x = event.which || event.keyCode;  // Use either which or keyCode, depending on browser support
Pankaj Chauhan
la source