Avant que nous en arrivions au clavier, veuillez noter que sur des appareils modernes il y a dâautres manières de ârécupérer quelque chose". Par exemple, les gens utilisent la reconnaissance vocale (en particulier sur les appareils mobiles) oubien le copier/coller avec la souris.
Donc si nous voulons contrôler une entrée dans un champ <input>, alors les évènements du clavier ne sont pas assez suffisants. Il y a un autre évènement nommé input pour gérer les changements dâun champ <input>, par nâimporte quelle moyen. Et il peut être un meilleur choix pour une telle tâche. Nous allons traiter cela plus tard dans le chapitre Les événements: change, input, cut, copy, paste.
Les évènements du clavier doivent être utilisés lorsquâon veut gérer les actions sur le clavier (Le clavier virtuel compte aussi). Par exemple, pour réagir sur les touches de directions Up et Down oubien les touches de raccourcis (y compris les combinaisons de touches).
Teststand
Pour mieux comprendre les évènements du clavier, vous pouvez utiliser le teststand en bas.
Essayez les différentes combinaisons de touches dans la zone de texte.
kinput.onkeydown = kinput.onkeyup = kinput.onkeypress = handle;
let lastTime = Date.now();
function handle(e) {
if (form.elements[e.type + 'Ignore'].checked) return;
area.scrollTop = 1e6;
let text = e.type +
' key=' + e.key +
' code=' + e.code +
(e.shiftKey ? ' shiftKey' : '') +
(e.ctrlKey ? ' ctrlKey' : '') +
(e.altKey ? ' altKey' : '') +
(e.metaKey ? ' metaKey' : '') +
(e.repeat ? ' (repeat)' : '') +
"\n";
if (area.value && Date.now() - lastTime > 250) {
area.value += new Array(81).join('-') + '\n';
}
lastTime = Date.now();
area.value += text;
if (form.elements[e.type + 'Stop'].checked) {
e.preventDefault();
}
}#kinput {
font-size: 150%;
box-sizing: border-box;
width: 95%;
}
#area {
width: 95%;
box-sizing: border-box;
height: 250px;
border: 1px solid black;
display: block;
}
form label {
display: inline;
white-space: nowrap;
}<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="style.css">
</head>
<body>
<form id="form" onsubmit="return false">
Prevent default for:
<label>
<input type="checkbox" name="keydownStop" value="1"> keydown</label>
<label>
<input type="checkbox" name="keyupStop" value="1"> keyup</label>
<p>
Ignore:
<label>
<input type="checkbox" name="keydownIgnore" value="1"> keydown</label>
<label>
<input type="checkbox" name="keyupIgnore" value="1"> keyup</label>
</p>
<p>Mettre le focus sur le champ d'entrée et appuyer une touche.</p>
<input type="text" placeholder="Press keys here" id="kinput">
<textarea id="area" readonly></textarea>
<input type="button" value="Clear" onclick="area.value = ''" />
</form>
<script src="script.js"></script>
</body>
</html>Keydown et keyup
Les évènements keydown surviennent lorsquâune touche est appuyée, et ensuite intervient keyup â lorsquâelle est relâchée.
event.code et event.key
La propriété key de lâobjet évènement permet dâobtenir un caractère, tandis que la propriété code de lâobjet évènement objet permet dâobtenir le âcode de la touche physiqueâ.
Par exemple, la même touche Z peut être appuyée avec ou sans Shift. Cela nous donne deux caractères différents : minuscule z et majuscule Z.
La propriété event.key est exactement le caractère, et il sera diffèrent. Cependant event.code est la même:
| Touche | event.key |
event.code |
|---|---|---|
| Z | z (minuscule) |
KeyZ |
| Shift+Z | Z (majuscule) |
KeyZ |
Si un utilisateur travaille avec des langues différentes, alors le fait de changer vers une autre langue aura pour effet de créer un caractère totalement diffèrent de "Z". Cela va devenir la valeur de event.key, tandis que event.code est toujours la même que: "KeyZ".
Chaque touche a un code qui dépend de sa position sur le clavier. Les codes des touches sont décrits dans le document Spécification des codes des évènements Interfaces Utilisateurs.
Par exemple:
- Les touches des lettres ont des codes de type:
"Key<letter>":"KeyA","KeyB"etc. - Les touches numériques ont des codes de type:
"Digit<number>":"Digit0","Digit1"etc. - Les touches spéciales sont codées par leurs noms:
"Enter","Backspace","Tab"etc.
Il existe plusieurs formats de claviers usuels, différents de par la présentation, et la spécification donne des codes pour les touches pour chacun dâentre eux.
voir la section alphanumérique de la specification pour plus de codes, ou essayez juste le teststand au-dessus.
"KeyZ", pas "keyZ"Semble être évident, mais beaucoup de gens font toujours des fautes.
Sâil vous plait éviter les fautes de frappes: câest KeyZ, pas keyZ. Le control tel que event.code=="keyZ" ne vas pas fonctionner: la première lettre de "Key" doit être une majuscule.
Et si une touche ne donne aucun caractère ? Par exemple, Shift ou F1 ou autres. Pour ces touches, event.key est approximativement la même chose que event.code :
| Key | event.key |
event.code |
|---|---|---|
| F1 | F1 |
F1 |
| Backspace | Backspace |
Backspace |
| Shift | Shift |
ShiftRight or ShiftLeft |
Veuillez noter que event.code spécifie exactement quelle touche est appuyée. Par exemple, la plupart des claviers ont deux touches de Shift: à gauche et à droite. La propriété event.code nous dit exactement laquelle fut appuyée, et event.key est responsable de la " signification " de la touche: comment il sâagit dâun (âShiftâ).
Disons, nous voulons gérer un raccourci : Ctrl+Z (ou Cmd+Z pour Mac). La plupart des éditeurs accrochent lâaction du âDefaireâ sur cette touche. Nous pouvons mettre un écouteur lorsquâon déclenche lâévènement keydown et chercher à savoir quelle touche est appuyée.
Il existe un dilemme ici: Dans cet écouteur dâévènement, devons-nous contrôler la valeur de event.key oubien event.code?
Dâune part, la valeur de event.key est un caractère, elle change en fonction de la langue. Si le visiteur a plusieurs langues dans le système dâexploitation et bascule entre elles, la même clé donne des caractères différents. Il est donc logique de vérifier event.code, câest toujours pareil.
Ainsi:
document.addEventListener('keydown', function(event) {
if (event.code == 'KeyZ' && (event.ctrlKey || event.metaKey)) {
alert('Undo!')
}
});
Dâautre part, il existe un problème avec event.code. Pour des dispositions de clavier différentes, la même touche peut avoir des caractères différents.
Par exemple, voici la disposition du clavier Américain (âQWERTYâ) et Allemand (âQWERTZâ) dessous (de Wikipedia) :
Pour la même touche, le clavier Américain a un âZâ, tandis que celui Allemand a un âYâ (les lettres sont échanges).
Donc, event.code sera égal à KeyZ pour les gens utilisant le clavier Allemand lorsquâils appuient sur Y.
Si on vérifie event.code == 'KeyZ' dans notre code, alors pour les personnes avec la disposition allemande ce genre de test passera quand ils appuient sur Y.
Cela semble être bizarre, mais câest ainsi. La specification mentionne explicitement ce comportement.
Donc, event.code peut correspondre à un caractère incorrect pour une disposition inattendue. Les mêmes lettres dans différentes disposition peuvent mapper sur différentes clés physiques, conduisant à des codes différents. Heureusement, cela ne se produit quâavec plusieurs codes, par exemple keyA, keyQ, keyZ (comme nous lâavons vu), et ne se produit pas avec des touches spéciales telles que Shift. Vous pouvez trouver la liste dans la specification.
Pour suivre de manière fiable les caractères dépendant de la disposition, event.key peut être un meilleur moyen.
Dâun autre côté, event.code a lâavantage de rester toujours le même, lié à lâemplacement de la clé physique. Ainsi, les raccourcis clavier qui en dépendent fonctionnent bien même en cas de changement de langue.
Voulons-nous gérer des clés dépendantes de la disposition ? Alors event.key est la voie à suivre.
Ou voulons-nous un raccourci clavier même après un changement de langue ? Alors, event.code peut être une meilleure option.
Auto-repeat
Si une touche est appuyée assez longtemps, elle commence la répétition avec la propriété âauto-repeatâ: lâévènement keydown se déclenche de manière répétitive, et ensuite lorsquâelle est relâchée nous obtenons finalement lâévènement keyup. Donc câest normal dâavoir plusieurs keydown et un unique évènement keyup.
Pour les évènements déclenchés par auto-repeat, lâévènement objet a une propriété event.repeat dont la valeur est assignée à true.
Actions par défaut
Les actions par défaut varient, comme il y a beaucoup de possibilités pouvant être initiées par le clavier.
Pa exemple:
- Un caractère apparait sur lâécran (le résultat le plus évident).
- Un caractère est supprimé (Delete key).
- Une page est défilée (PageDown key).
- Le navigateur ouvre la boite de dialogue âSauvegarder la Pageâ dialog (Ctrl+S)
- â¦ainsi de suite.
Lâempêchement de lâaction par défaut à lâévènement keydown peut annuler la plupart dâentre elles, à lâexception des touches spéciales spécifiques aux systèmes dâexploitations. Par exemple, sur Windows Alt+F4 ferme la fenêtre en cours du navigateur. Et il nâexiste aucun moyen de lâarrêter en empêchant lâaction par défaut JavaScript.
Par exemple, la balise <input> en bas sâattend à recevoir un numéro de téléphone, alors elle nâaccepte que les touches numériques, +, () oubien -:
<script>
function checkPhoneKey(key) {
return (key >= '0' && key <= '9') || ['+','(',')','-'].includes(key);
}
</script>
<input onkeydown="return checkPhoneKey(event.key)" placeholder="Phone, please" type="tel">
Le gestionnaire onkeydown utilise ici checkPhoneKey pour vérifier la touche enfoncée. Sâil est valide (de 0..9 ou lâun des +-()), alors il renvoie true, sinon false.
Comme nous le savons, la valeur false renvoyée par le gestionnaire dâévénements, attribuée à lâaide dâune propriété DOM ou dâun attribut, comme ci-dessus, empêche lâaction par défaut, donc rien nâapparaît dans le <input> pour les clés qui ne passent pas le test. (La valeur âtrueâ renvoyée nâaffecte rien, seul le renvoi de âfalseâ compte)
Veuillez noter que les touches spéciales, telles que Backspace, Left, Right, ne fonctionnent pas dans lâinput. Câest un effet secondaire du filtre strict checkPhoneKey. Ces clés lui font retourner false.
Détendons un peu le filtre en autorisant les touches fléchées Left, Right et Delete, Backspace :
<script>
function checkPhoneKey(key) {
return (key >= '0' && key <= '9') ||
['+','(',')','-','ArrowLeft','ArrowRight','Delete','Backspace'].includes(key);
}
</script>
<input onkeydown="return checkPhoneKey(event.key)" placeholder="Phone, please" type="tel">
maintenant les flèches et la suppression marchent bien.
Même si nous avons le filtre de clavier, on peut toujours entrer nâimporte quoi à lâaide dâune souris et faire un clic droit + Coller. Les appareils mobiles offrent dâautres moyens de saisir des valeurs. Le filtre nâest donc pas fiable à 100%.
Lâapproche alternative serait de suivre lâévénement oninput â il se déclenche après toute modification. Là , nous pouvons vérifier le nouveau input.value et le modifier/mettre en surbrillance le <input> lorsquâil est invalide. Ou nous pouvons utiliser les deux gestionnaires dâévénements ensemble.
Héritage
Dans le passé, il yâavait un évènement keypress, et aussi les propriétés keyCode, charCode, which de lâobjet évènement.
Il y avait tellement dâincompatibilités au niveau des navigateurs en travaillant avec eux que les développeurs de la spécification nâavaient autre moyen que de les déprécier tous et dâen créer de nouveaux et plus modernes (tels que ceux décrits en haut dans ce chapitre). Lâancien code marche encore, étant donné que les navigateurs continuent de les supporter, mais nous nâavons nullement besoin de les utiliser maintenant.
Claviers mobiles
Lors de lâutilisation de claviers virtuels / mobiles, officiellement appelés IME (Input-Method Editor), la norme W3C indique quâun KeyboardEvent e.keyCode devrait être 229 et e.key devrait être "Unidentified".
Bien que certains de ces claviers puissent toujours utiliser les bonnes valeurs pour e.key, e.code, e.keyCode, ⦠lorsque vous appuyez sur certaines touches telles que les flèches ou le retour arrière, il nây a aucune garantie, donc la logique de votre clavier peut ne pas toujours fonctionner sur les appareils mobiles.
Résumé
Le fait dâappuyer sur une touche génère toujours un évènement du clavier, que cela soit une touche de symbole ou des touches spéciales telles que Shift oubien Ctrl et ainsi de suite. La seule exception est la touche Fn qui est dès fois présente sur un clavier dâordinateur portable. Il nây a pas dâévènement de clavier pour cela, parce que cela est implémenté à un niveau plus bas que celui du system dâexploitation.
Les Evènements du Clavier:
keydownâ en appuyant sur la touche (auto-repeats répète automatiquement si un appui long de la touche est effectué),keyupâ en relâchant la touche.
Les propriétés principales des évènements du clavier:
codeâ la propriété âkey codeâ ("KeyA","ArrowLeft"ainsi de suite), spécifique à la position physique de la touche sur le clavier.keyâ le caractère ("A","a"et ainsi de suite), pour les touches ne prenant pas en charge les caractères, telles que Esc, a souvent la même valeur quecode.
Dans le passé, les évènements du clavier étaient des fois utilisés pour contrôler les entrées dans les champs de formulaires. Cela nâest pas fiable, parce que les données recueillies peuvent provenir de plusieurs sources. Nous avons les évènements input et change pour gérer toute entrée de donnée (traitée plus tard dans le chapitre Les événements: change, input, cut, copy, paste). Elles se déclenchent après toute sorte dâentrée, y compris le copier-coller oubien la reconnaissance vocale.
Nous devons utiliser les évènements du clavier quand nous voulons vraiment utiliser le clavier. Par exemple, pour réagir aux raccourcis ou touches spéciales.
Commentaires
<code>, pour plusieurs lignes â enveloppez-les avec la balise<pre>, pour plus de 10 lignes - utilisez une sandbox (plnkr, jsbin, codepenâ¦)