Met le premier caractère en majuscule
Dans cet article, nous allons étudier plus en détail les événements de la souris et leurs propriétés.
Veuillez noter que ces événements peuvent provenir non seulement des "périphériques souris", mais aussi d'autres périphériques, comme les téléphones et les tablettes, où ils sont émulés pour des raisons de compatibilité.
...Il existe également plusieurs autres événements, que nous aborderons plus tard.
Les événements liés au clic ont toujours la propriété button, qui permet d'obtenir le bouton exact de la souris.
En général, nous ne l'utilisons pas pour les événements liés au clic et au menu contextuel, car le premier ne se produit que lors d'un clic gauche, et le second - uniquement lors d'un clic droit.
Mais, les gestionnaires de mousedown et de mouseup peuvent avoir besoin de event.button, car ces événements se déclenchent sur n'importe quel bouton, et le bouton permet de distinguer le "mousedown droit" du "mousedown gauche".
Les valeurs possibles de event.button sont :
État du bouton | event.button |
---|---|
Bouton de gauche (principal) | 0 |
Bouton du milieu (auxiliaire) | 1 |
Bouton droit (secondaire) | 2 |
La plupart des souris ne possèdent que les boutons gauche et droit, les valeurs possibles sont donc 0 ou 2. Les périphériques tactiles génèrent également des événements similaires lorsque l'on tape dessus.
Comme vous pouvez le constater dans la liste ci-dessus, une action utilisateur peut déclencher plusieurs événements.
Par exemple, un clic sur le bouton gauche déclenche d'abord le mousedown, lorsque le bouton est enfoncé, puis le mouseup et le click lorsqu'il est relâché.
Dans le cas où une action unique déclenche plusieurs événements, leur ordre est fixe. C'est-à-dire que les gestionnaires sont toujours appelés dans l'ordre mousedown → mouseup → click.
Voici un exemple qui va vous montrer tout ce qu’on vient de dire
Code
<!DOCTYPE html> <html lang="fr"><head> <meta charset="utf-8"> <title>Exemple événements de la souris en JavaScript</title> <script> { var timer = 0; function voirMessage(txt, form) { if (timer == 0) { timer = new Date(); } let tm = new Date(); if (tm - timer > 300) { txt = '------------------------------\n' + txt; } let str = document.forms[form + 'form'].getElementsByTagName('textarea')[0]; str.value += txt + '\n'; str.scrollTop = str.scrollHeight; timer = tm;} function evsouris(e) { let evt = e.type; while (evt.length < 11){ evt += ' '; voirMessage(evt + " button=" + e.button, 'test')} return false; } function logClear(form) { timer = 0; document.forms[form+'form'].getElementsByTagName('textarea')[0].value =''; lines = 0; } } </script> </head> <body> <div> <form id="testform" name="testform"> <p><input onmousedown="return evsouris(event)" onmouseup="return evsouris(event)" onclick="return evsouris(event)" oncontextmenu="return evsouris(event)" ondblclick="return evsouris(event)" value="Cliquer ici droit | gauche de la souris" type="button"> </p> < textarea style="font-size:12px;height:250px;width:200px;"></textarea> <p><input onclick="logClear('test')" value=" Effacer " type="button"></p> </form> </div> </body> </html>
Exécuter ce code dans votre navigateur.
Cliquez sur le bouton et maintenez le bouton enfoncé pour un court instant puis relâchez, vous verrez les événements qui se sont créés et leur ordre. Essayez aussi le double-clique. Faites aussi un clique droit ou un clique avec le bouton central de la souri.
Sur le banc d'essai dans le code ci dessus, tous les événements de souris sont enregistrés, et s'il y a plus d'une seconde de délai entre eux, ils sont séparés par une ligne horizontale.
On peut également voir la propriété button qui nous permet de détecter le bouton de la souris.
Tous les événements de souris incluent les informations sur les touches de modification pressées.
Propriétés de l'événement :
shiftKey : Shift
altKey : Alt (ou Opt pour Mac)
ctrlKey : Ctrl
metaKey : Cmd pour Mac
Ils sont vrais si la touche correspondante a été pressée pendant l'événement.
Par exemple, le bouton ci-dessous ne fonctionne que si vous appuyez sur Alt+Shift+clic :
Code
<button id="button">Alt+Shift+Click!</button> <script> button.onclick = function(event) { if (event.altKey && event.shiftKey) { alert('Hooray!'); } }; </script>
Même si nous voulons forcer les utilisateurs de Mac à utiliser Ctrl+clic, c'est assez difficile.
Le problème est le suivant : un clic gauche avec Ctrl est interprété comme un clic droit sur MacOS, et cela génère l'événement contextuel, et non un clic comme sur Windows/Linux.
Donc, si nous voulons que les utilisateurs de tous les systèmes d'exploitation se sentent à l'aise, nous devrions vérifier metaKey en même temps que ctrlKey.
Pour le code JS, cela signifie que nous devrions vérifier si (event.ctrlKey || event.metaKey).
Il existe aussi des appareils mobiles
Les combinaisons de claviers sont un bon complément au flux de travail. Ainsi, si le visiteur utilise un clavier, elles fonctionnent.
Mais si leur appareil n'en est pas équipé, il doit y avoir un moyen pour fonctionner sans les touches de modification.
Le double-clic de la souris a un effet secondaire qui peut être gênant dans certaines interfaces : il sélectionne le texte.
Par exemple, un double-clic sur le texte ci-dessous le sélectionne en plus de notre gestionnaire :
<span ondblclick="alert(' Le dblclick provoque une sélection ')">Double-click ici</span>
Si l'on appuie sur le bouton gauche de la souris et que, sans le relâcher, on déplace la souris, cela fait également une sélection, souvent non désirée.
Il existe plusieurs façons d'empêcher la sélection.
Dans notre cas, le moyen le plus raisonnable est d'empêcher l'action du navigateur lors du déplacement de la souris. Cela empêche ces deux sélections :
<span ondblclick="alert(' Le dblClick! ne provoque plus la sélection ')" onmousedown="return false"> Double-click ici </span>
Désormais, le texte n'est pas sélectionné en cas de double-clic, et le fait d'appuyer sur le bouton gauche ne permet pas de lancer la sélection.
Remarque : le texte qu'il contient peut toujours être sélectionné. Cependant, la sélection ne doit pas commencer sur le texte lui-même, mais avant ou après. En général, cela convient aux utilisateurs.
Entrons dans le détail des événements qui se produisent lorsque la souris se déplace entre les éléments.
L'événement mouseover se produit lorsque le pointeur de la souris arrive sur un élément, et mouseout - lorsqu'il le quitte.
Ces événements sont spéciaux, car ils ont la propriété relatedTarget. Cette propriété complète la cible. Lorsque la souris quitte un élément pour un autre, l'un d'eux devient target, et l'autre - relatedTarget.
Pour le mouseover :
event.target - est l'élément sur lequel la souris est passée.
event.relatedTarget - est l'élément d'où la souris est venue (relatedTarget → target).
Pour le mouseout, c'est l'inverse :
event.target - est l'élément que la souris a quitté.
event.target - est l'élément que la souris a quitté.
event.relatedTarget - est le nouvel élément sous le pointeur, pour lequel la souris est partie (target → relatedTarget).
Chaque évènement possède les informations concernant à la fois target et relatedTarget .
Voici un exemple qui mis en évidence touts les événements relatives au mouvement de la sourie :
Code
<!DOCTYPE html> <html lang="fr"><head> <meta charset="utf-8"> <title>Evénement généré par le déplacement de la souris </title> <link rel="stylesheet" href="style.css"> </head> <body> <div class="conteneur" id="container"> <div class="Le-Vert"> <div class="œil-gauche"></div> <div class="œil-droit"></div> <div class="smile"></div> </div> <div class="Le-Jaune"> <div class="œil-gauche"></div> <div class="œil-droit"></div> <div class="smile"></div> </div> <div class="Le-Rouge"> <div class="œil-gauche"></div> <div class="œil-droit"></div> <div class="smile"></div> </div> </div> <form id="testform" name="testform"> <textarea name="textarea" id="log">Les événements vont apparaître ici !</textarea> <p><input onclick="document.forms['testform'].getElementsByTagName('textarea')[0].value ='Les événements vont apparaître ici !';" value=" Effacer " type="button"></p> </form> <script> container.onmouseover = container.onmouseout = handler; function handler(event) { function str(el) { if (!el) return "null" return el.className || el.tagName; } log.value += event.type + ': ' + 'target=' + str(event.target) + ', relatedTarget=' + str(event.relatedTarget) + "\n"; log.scrollTop = log.scrollHeight; } </script> </body> </html>
Et voici le code fichier style.css qui va avec :
Code
body, html { margin: 10px; padding: 0; } #container { border: 1px solid brown; padding: 10px; width: 330px; margin-bottom: 5px; box-sizing: border-box; } #log { height: 300px; width: 500px; display: block; box-sizing: border-box; } [class^="smiley-"] { display: inline-block; width: 70px; height: 70px; border-radius: 50%; margin-right: 20px; } .smiley-green { background: #a9db7a; border: 5px solid #92c563; position: relative; } .smiley-green .left-eye { width: 18%; height: 18%; background: #84b458; position: relative; top: 29%; left: 22%; border-radius: 50%; float: left; } .smiley-green .right-eye { width: 18%; height: 18%; border-radius: 50%; position: relative; background: #84b458; top: 29%; right: 22%; float: right; } .smiley-green .smile { position: absolute; top: 67%; left: 16.5%; width: 70%; height: 20%; overflow: hidden; } .smiley-green .smile:after, .smiley-green .smile:before { content: ""; position: absolute; top: -50%; left: 0%; border-radius: 50%; background: #84b458; height: 100%; width: 97%; } .smiley-green .smile:after { background: #84b458; height: 80%; top: -40%; left: 0%; } .smiley-yellow { background: #eed16a; border: 5px solid #dbae51; position: relative; } .smiley-yellow .left-eye { width: 18%; height: 18%; background: #dba652; position: relative; top: 29%; left: 22%; border-radius: 50%; float: left; } .smiley-yellow .right-eye { width: 18%; height: 18%; border-radius: 50%; position: relative; background: #dba652; top: 29%; right: 22%; float: right; } .smiley-yellow .smile { position: absolute; top: 67%; left: 19%; width: 65%; height: 14%; background: #dba652; overflow: hidden; border-radius: 8px; } .smiley-red { background: #ee9295; border: 5px solid #e27378; position: relative; } .smiley-red .left-eye { width: 18%; height: 18%; background: #d96065; position: relative; top: 29%; left: 22%; border-radius: 50%; float: left; } .smiley-red .right-eye { width: 18%; height: 18%; border-radius: 50%; position: relative; background: #d96065; top: 29%; right: 22%; float: right; } .smiley-red .smile { position: absolute; top: 57%; left: 16.5%; width: 70%; height: 20%; overflow: hidden; } .smiley-red .smile:after, .smiley-red .smile:before { content: ""; position: absolute; top: 50%; left: 0%; border-radius: 50%; background: #d96065; height: 100%; width: 97%; } .smiley-red .smile:after { background: #d96065; height: 80%; top: 60%; left: 0%; }
L'événement mousemove se déclenche lorsque la souris se déplace. Mais cela ne signifie pas que chaque pixel mène à un événement.
Le navigateur vérifie la position de la souris de temps en temps. Et s'il remarque des changements, il déclenche les événements.
Cela signifie que si le visiteur déplace la souris très rapidement, certains éléments du DOM peuvent être ignorés .
C'est une bonne chose pour les performances, car il peut y avoir de nombreux éléments intermédiaires. Nous n'avons pas vraiment envie d'entrer et de sortir de chacun d'eux.
D'un autre côté, il ne faut pas oublier que le pointeur de la souris ne "visite" pas tous les éléments en cours de route. Il peut "sauter".
En particulier, il est possible que le pointeur saute en plein milieu de la page depuis l'extérieur de la fenêtre. Dans ce cas, relatedTarget est nul, car il ne vient de "nulle part".
Vous pouvez le vérifier "en direct" sur un banc d'essai dont le code ci-dessous.
Son HTML comporte deux éléments imbriqués : la <div id=" enfant "> est à l'intérieur de la <div id=" parent ">. Si vous déplacez rapidement la souris au-dessus d'eux, alors peut-être que seule la <div id=" enfant " déclenchera des événements, ou peut-être celle du parent, ou peut-être qu'il n'y aura pas d'événements du tout.
Placez également le pointeur dans la division enfant, puis déplacez-le rapidement vers le bas. Si le mouvement est suffisamment rapide, l'élément parent est ignoré. La souris traversera l'élément parent sans s'en apercevoir.
Code
<!doctype html> <html> <head> <meta charset="UTF-8"> <title>Evénement de mouvement de la souris : Saut d'éléments</title> <style> #parent { background: #99C0C3; width: 160px; height: 120px; position: relative; } #enfant { background: #FFDE99; width: 50%; height: 50%; position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); } textarea { height: 140px; width: 300px; display: block; } </style> </head> <body> <div id="parent">Elément parent <div id="enfant">Elément enfant</div> </div> <textarea id="text"></textarea> <input onclick="clearText()" value="Effacer" type="button"> <script> let parent = document.getElementById('parent'); parent.onmouseover = parent.onmouseout = parent.onmousemove = handler; function handler(event) { let type = event.type; while (type.length < 11) type += ' '; log(type + " target=" + event.target.id) return false; } function clearText() { text.value = ""; lastMessage = ""; } let lastMessageTime = 0; let lastMessage = ""; let repeatCounter = 1; function log(message) { if (lastMessageTime == 0) lastMessageTime = new Date(); let time = new Date(); if (time - lastMessageTime > 500) { message = '------------------------------\n' + message; } if (message === lastMessage) { repeatCounter++; if (repeatCounter == 2) { text.value = text.value.trim() + ' x 2\n'; } else { text.value = text.value.slice(0, text.value.lastIndexOf('x') + 1) + repeatCounter + "\n"; } } else { repeatCounter = 1; text.value += message + "\n"; } text.scrollTop = text.scrollHeight; lastMessageTime = time; lastMessage = message; } </script> </body> </html>
Une caractéristique importante du mouseout, il se déclenche, lorsque le pointeur se déplace d'un élément à son descendant, par exemple de #parent à #enfant.
Si nous sommes sur #parent et que nous déplaçons le pointeur plus profondément dans #enfant, nous obtenons le mouseout sur #parent !
Cela peut sembler étrange, mais s'explique facilement.
Selon la logique du navigateur, le curseur de la souris ne peut se trouver qu'au-dessus d'un seul élément à la fois - l'élément le plus imbriqué et le plus haut selon l'indice z.
Ainsi, s'il passe à un autre élément (même descendant), il quitte l'élément précédent.
Veuillez noter un autre détail important du traitement des événements.
L'événement de survol d'un élément descendant s'étend vers le haut. Donc, si #parent a un gestionnaire de mouseover, il se déclenche :
Vous pouvez très bien le voir dans l'exemple ci-dessous : <div id="enfant"> est à l'intérieur de la <div id="parent">. Il y a des gestionnaires de mouseover/out sur l'élément #parent qui sortent les détails de l'événement.
Si vous déplacez la souris de #parent à #enfant, vous voyez deux événements sur #parent :
mouseout [target : parent] (quitte le parent), puis
mouseover [target : enfant] (arrive à l'enfant,).
Code
<!doctype html> <html> <head> <meta charset="UTF-8"> <title>Evénement de mouvement de la souris : Saut d'éléments</title> <style> #parent { background: #99C0C3; width: 160px; height: 120px; position: relative; } #enfant { background: #FFDE99; width: 50%; height: 50%; position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); } textarea { height: 140px; width: 300px; display: block; } </style> </head> <body> <div id="parent" onmouseover="mouselog(event)" onmouseout="mouselog(event)">Elément parent <div id="enfant">Elément enfant</div> </div> <textarea id="text"></textarea> <input type="button" onclick="text.value=''" value="Effacer"> <script> function mouselog(event) { let d = new Date(); text.value += `${d.getHours()}:${d.getMinutes()}:${d.getSeconds()} | ${event.type} [target: ${event.target.id}]\n`.replace(/(:|^)(\d\D)/, '$10$2'); text.scrollTop = text.scrollHeight; } </script> </body> </html>
Et voilà nous avons fait le tour dans la plus part des événement de la souris, il reste quelques uns que nous utilisons presque jamais
créer par carabde le 4 fevrier 2022