KeyboardEvent.keyCode obsolète. Qu'est-ce que cela signifie en pratique?

92

Selon MDN, nous ne devrions certainement pas utiliser la .keyCodepropriété. Il est obsolète:

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

Sur l'école W3, ce fait est minimisé et il n'y a qu'une note latérale indiquant que .keyCodec'est uniquement fourni pour la compatibilité et que la dernière version de la spécification des événements DOM recommande d'utiliser la .keypropriété à la place.

Le problème est que ce .keyn'est pas pris en charge par les navigateurs, alors que devrions-nous utiliser? Y a-t-il quelque chose qui me manque?

Jason210
la source
3
.keyest pris en charge dans tous les principaux navigateurs developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/...
Sinan Bolel

Réponses:

32

Vous avez trois façons de le gérer, tel qu'il est écrit sur le lien que vous avez partagé.

if (event.key !== undefined) {

} else if (event.keyIdentifier !== undefined) {

} else if (event.keyCode !== undefined) {

}

vous devriez les envisager, c'est la bonne façon si vous voulez un support multi-navigateurs.

Cela pourrait être plus facile si vous implémentez quelque chose comme ça.

var dispatchForCode = function(event, callback) {
  var code;

  if (event.key !== undefined) {
    code = event.key;
  } else if (event.keyIdentifier !== undefined) {
    code = event.keyIdentifier;
  } else if (event.keyCode !== undefined) {
    code = event.keyCode;
  }

  callback(code);
};
Miguel Lattuada
la source
13
J'ai lu cela mais il semblait y avoir beaucoup de code supplémentaire pour aucune autre raison que MDN a dit que quelque chose est obsolète, alors que cela fonctionne correctement dans tous les principaux navigateurs. Mais si c'est la bonne façon, merci!
Jason210
3
Wow regarde ça. caniuse.com/#search=keyCode (Cette propriété KeyboardEvent est prise en charge dans tous les navigateurs (depuis IE6 +, Firefox 2+, Chrome 1+, etc. "parlant de .keyCode)
Miguel Lattuada
2
C'est ce qui est si ennuyeux dans tout cela. Tous les principaux navigateurs prennent en charge keyCode, mais essayez de vérifier la propriété .key, qui est la propriété recommandée, et ne l'utilisez presque pas!
Jason210
4
Oui, nous sommes à la fin du mois de mai 2016, et chrome a finalement implémenté la propriété KeyboardEvent.key. Safari, ainsi que tous les navigateurs mobiles, n'a pas encore rejoint le groupe "16,5% de tous les utilisateurs". De plus, malheureusement, Microsoft Edge et Gecko codent un certain nombre d'événements différemment, par exemple: l'événement clé pour la flèche vers le haut est codé comme "Up" au lieu de "ArrowUp".
Joshua Dawson
Je pense que cela vous aidera à stackoverflow.com/questions/41465542/…
Maven97
26

De plus, tous les keyCode , qui , charCode et keyIdentifier sont obsolètes:
charCodeet ne keyIdentifiersont pas des fonctionnalités standard.
keyIdentifierest supprimé à partir de Chrome 54 et Opera 41.0
keyCoderenvoie 0, lors d'un événement de pression de touche avec des caractères normaux sur FF.

La propriété clé :

 readonly attribute DOMString key

Contient une valeur d'attribut clé correspondant à la touche enfoncée

Au moment d'écrire ces lignes, la keypropriété est prise en charge par tous les principaux navigateurs à partir de: Firefox 52, Chrome 55, Safari 10.1, Opera 46. Sauf Internet Explorer 11 qui a: des identifiants de clé non standard et un comportement incorrect avec AltGraph. Plus d'informations
Si cela est important et / ou la compatibilité descendante l'est, vous pouvez utiliser la détection de fonctionnalités comme dans le code suivant:

Notez que la keyvaleur est différente de keyCodeou whichproperties en ce que: elle contient le nom de la clé et non son code. Si votre programme a besoin de codes de caractères, vous pouvez utiliser charCodeAt(). Pour les caractères imprimables uniques, vous pouvez utiliser charCodeAt(), si vous avez affaire à des clés dont les valeurs contiennent plusieurs caractères, comme le ArrowUp sont les chances: vous testez des clés spéciales et prenez des mesures en conséquence. Essayez donc la mise en œuvre d' une table des valeurs clés et les codes correspondants charCodeArr["ArrowUp"]=38, charCodeArr["Enter"]=13, charCodeArr[Escape]=27... et ainsi de suite, s'il vous plaît jeter un oeil à des valeurs clés et leurs codes correspondants

if(e.key!=undefined){
        var characterCode = charCodeArr[e.key] || e.key.charCodeAt(0);
    }else{
        /* As @Leonid suggeted   */
        var characterCode = e.which || e.charCode || e.keyCode || 0;
    }
        /* ... code making use of characterCode variable  */  

Peut-être souhaitez-vous envisager la compatibilité ascendante, c'est-à-dire utiliser les propriétés héritées tant qu'elles sont disponibles, et uniquement lorsqu'elles sont supprimées, passez aux nouvelles:

if(e.which || e.charCode || e.keyCode ){
        var characterCode = e.which || e.charCode || e.keyCode;
    }else if (e.key!=undefined){
        var characterCode = charCodeArr[e.key] || e.key.charCodeAt(0);
    }else{
        var characterCode = 0;
    }

Voir aussi: la documentation sur la KeyboardEvent.codepropriété et quelques détails supplémentaires dans cette réponse .

user10089632
la source
Votre solution ne fonctionne pas dans mon navigateur (Windows 10, Chrome 60, clavier belge). Tout d'abord, la charCodeArrfonction n'existe pas. De plus, charCodeAtne fonctionne pas pour toutes les valeurs de e.key. Par exemple, pour la clé Enter/ Return, la valeur de la e.keypropriété est "Enter", et l'exécution charCodeArrpour cette chaîne renvoie la valeur 69(qui est le code ASCII du caractère E).
John Slegers
@JohnSlegers, oui c'était une faute de frappe, je voulais dire un tableau créé par l'utilisateur. S'il vous plaît, consultez ma réponse mise à jour pour plus de détails.
user10089632
19

TLDR: Je vous suggère que vous devriez utiliser la nouvelle event.keyet event.codepropriétés au lieu des anciens. IE et Edge prennent en charge ces propriétés, mais ne prennent pas encore en charge les nouveaux noms de clé. Pour eux, il y a un petit polyfill qui leur permet de sortir les noms de clé / code standard:

https://github.com/shvaikalesh/shim-keyboard-event-key


Je suis venu à cette question en recherchant la raison du même avertissement MDN que OP. Après avoir cherché un peu plus, le problème avec keyCodedevient plus clair:

Le problème avec l'utilisation keyCodeest que les claviers non anglais peuvent produire différentes sorties et même les claviers avec différentes dispositions peuvent produire des résultats incohérents. De plus, il y avait le cas de

Si vous lisez la spécification W3C: https://www.w3.org/TR/uievents/#interface-keyboardevent

En pratique, keyCode et charCode sont incohérents entre les plates-formes et même la même implémentation sur différents systèmes d'exploitation ou en utilisant des localisations différentes.

Il va dans une certaine profondeur en décrivant ce qui n'allait pas avec keyCode: https://www.w3.org/TR/uievents/#legacy-key-attributes

Ces fonctionnalités n'ont jamais été officiellement spécifiées et les implémentations actuelles du navigateur varient de manière significative. La grande quantité de contenu hérité, y compris les bibliothèques de scripts, qui repose sur la détection de l'agent utilisateur et sur l'action en conséquence signifie que toute tentative de formalisation de ces attributs et événements hérités risquerait de casser autant de contenu qu'elle en aurait corrigé ou permis. En outre, ces attributs ne conviennent pas à une utilisation internationale et ne répondent pas aux problèmes d'accessibilité.

Donc, après avoir établi la raison pour laquelle l'ancien keyCode a été remplacé, voyons ce que vous devez faire aujourd'hui:

  1. Tous les navigateurs modernes prennent en charge les nouvelles propriétés ( keyet code).
  2. IE et Edge prennent en charge une version plus ancienne de la spécification, qui porte des noms différents pour certaines clés. Vous pouvez utiliser une cale pour cela: https://github.com/shvaikalesh/shim-keyboard-event-key (ou rouler le vôtre - c'est plutôt petit de toute façon)
  3. Edge a corrigé ce bogue dans la dernière version (sera probablement publiée en avril 2018) - https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/8860571/
  4. Reportez-vous à la liste des clés d'événement que vous pouvez utiliser: https://www.w3.org/TR/uievents-key/
Kumarharsh
la source
Selon le MDN , ni Internet Explorer ni Edge ne prennent en chargeKeyboardEvent.code. En outre, les valeurs dekeyetcodedépendent du navigateur. Les deux problèmes fontkeyetcodepas pratique à utiliser dans des applications réelles.
John Slegers
@JohnSlegers s'il vous plaît voir developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key
kumarharsh
Si je veux tester les touches fléchées, page haut / bas, accueil et fin, dois-je utiliser keyou code? C'est généralement une clé physique, mais cela peut aussi dépendre du verrouillage numérique et de la disposition ... Quelle est la meilleure pratique?
Jake
12

MDN a déjà fourni une solution:

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

window.addEventListener("keydown", function (event) {
  if (event.defaultPrevented) {
    return; // Should do nothing if the default action has been cancelled
  }

  var handled = false;
  if (event.key !== undefined) {
    // Handle the event with KeyboardEvent.key and set handled true.
  } else if (event.keyIdentifier !== undefined) {
    // Handle the event with KeyboardEvent.keyIdentifier and set handled true.
  } else if (event.keyCode !== undefined) {
    // Handle the event with KeyboardEvent.keyCode and set handled true.
  }

  if (handled) {
    // Suppress "double action" if event handled
    event.preventDefault();
  }
}, true);
Vicky Gonsalves
la source
3
Malheureusement, keyest une valeur de chaîne spécifique au navigateur comme "Enter"ou "ArrowUp"et il n'y a pas de moyen standardisé de la convertir en code correspondant. vous aurez donc besoin d'encore plus de code standard pour convertir entre clé et code.
John Slegers
6

Par exemple, si vous souhaitez détecter si la touche "Entrée" a été cliquée ou non:

Au lieu de

event.keyCode === 13

Fais-le comme

event.key === 'Enter'
Thomas Gotwig
la source