Javascript (14) - Gestion avancée d'événements

Dans cette leçon, le formateur explique les techniques avancées de gestion des événements en JavaScript. Il commence par rappeler la méthode traditionnelle consistant à placer l’attribut HTML onclick directement dans la balise, puis montre comment assigner un gestionnaire via le code JavaScript (document.getElementById('orange').onclick = function() { … }). Il souligne le problème d’ordre de chargement du DOM et recommande de placer le script après les éléments HTML. Ensuite, il introduit la méthode recommandée : addEventListener, en détaillant ses trois paramètres (type d’événement sans le préfixe « on », fonction anonyme, booléen de capture). Il montre que, contrairement à l’attribut onclick, addEventListener permet d’attacher plusieurs gestionnaires au même élément. À l’aide de deux divs imbriquées (orange contenant jaune), il illustre la propagation des événements, expliquant les phases de capture (descendante) et de bouillonnement (montante) et comment le booléen du troisième argument inverse l’ordre d’exécution. Enfin, il résume les trois approches possibles (attribut HTML, affectation directe via .onclick, et addEventListener) en soulignant que la dernière est la plus flexible et recommandée.
Chapters
Bonjour à tous et bienvenue dans cette nouvelle leçon de JavaScript. Aujourd'hui, nous allons découvrir une autre manière de gérer les événements. Jusqu'ici, pour prendre en compte un événement, on déclare le gestionnaire d'événements en local sur la balise concernée en tant qu'attribut HTML. Par exemple, si on examine le code suivant, dans la balise body on dispose de 2 divs, une Une identifiée par orange et l'autre qui est identifiée par jaune. Imaginons que l'on veut déclarer un gestionnaire d'événements sur la balise orange. Alors on va mettre onclick et on lui associe la fonction JavaScript souhaitée. Imaginons que la fonction est déjà créée et elle s'appelle f. Autrement dit, quand je clique sur la div identifiée par orange, dans ce cas l'événement clic sera détecté et il fera appel à la fonction f. Cependant, il existe d'autres méthodes qui sont plus avancées qui permettent de gérer les événements. Et on va commencer par la première technique. Tout d'abord, on va ouvrir un bloc de script et dedans nous allons cibler l'objet concerné par l'événement, à savoir la balise identifiée par orange. Donc on mettra document.getElementById .getElementById orange. Et ensuite on va ajouter directement le nom de l'événement de la manière suivante: onclick. Dans ce cas tout doit être écrit en minuscule. Ça veut dire que ce gestionnaire d'événements il concerne la balise identifiée par orange. Donc quand l'événement clic sera détecté sur cet objet-là, on va tout simplement lui associer un traitement de la manière suivante. Donc on va mettre ici égal et on met le mot-clé function puis on ouvre les accolades. En réalité, nous avons associé directement une fonction à l'événement quand il sera détecté sur l'objet concerné. On appelle cette fonction une fonction anonyme parce que c'est une fonction qui n'a pas de nom. Autrement dit, cette fonction sera déclarée et exécutée simultanément. Et là, on va tout simplement mettre quelque chose du genre alerte Bonjour. Donc quand je vais cliquer sur la div identifiée par orange, j'exécuterai la fonction anonyme qui va afficher le message Bonjour. Cependant, c'est pas vraiment ce qui va se passer. Examinons d'abord pour voir le résultat. Je clique sur la div orange et il se passe vraiment rien. En réalité, c'est une erreur JavaScript. Pourquoi? Parce que le navigateur va lire le code ligne par ligne et quand il arrivera à cette ligne, il va chercher un objet identifié par orange qu'il n'a pas encore chargé, c'est-à-dire la déclaration de l'objet en tant que JavaScript précède sa déclaration en HTML. Donc je cherche un objet qui n'a pas encore été intégré au DOM puisque la page n'est pas encore entièrement chargée. Alors dans ce cas, il faut déplacer le script après le chargement de l'objet. On va tout simplement prendre le script et on va le mettre juste avant la fermeture de body. Bien sûr, on peut le mettre après /body, voire même après /html, mais il est de coutume de placer ses scripts juste avant la fermeture de la balise body, c'est-à-dire avant /body. Dans ce cas, quand j'exécute, on voit bien que le JavaScript fonctionne normalement. Alors ici, c'est une méthode qui permet de déclarer des gestionnaires d'événements sur des objets sans être obligé de les déclarer en tant qu'attributs HTML sur l'objet lui-même. Et ça nous permet de placer le code JavaScript dans un seul endroit au lieu de l'éparpiller un peu partout dans notre document. Jusqu'ici, tout a l'air bon. Mais supposons maintenant que je vais déclarer le même gestionnaire d'événements sur le même objet mais mais avec un traitement différent. Autrement dit, je vais copier ce bout de code et je vais le coller juste après, et je vais changer de message. Au lieu de Bonjour, je vais mettre Bonsoir. Donc vous avez constaté que l'objet c'est lui-même et l'événement c'est lui-même, mais j'ai déclaré ça 2 fois de suite. Alors quand j'exécute, on va voir que seulement le dernier gestionnaire d'événements est pris en considération, à savoir celui qui va afficher le message Bonsoir. Autrement dit, c'est comme si cet événement n'a pas été détecté sur l'objet. Et ça, ça constitue un inconvénient de cette méthode. Ceci va nous conduire à la méthode suivante. Alors je vais considérer que l'objet concerné par l'événement c'est toujours le même, c'est-à-dire la div identifiée par orange, mais cette fois-ci au lieu de mettre directement l'événement onclick, je vais faire appel à la méthode addEventListener. La méthode addEventListener permet tout simplement d'instaurer un gestionnaire d'événements sur l'objet courant, à savoir dans ce cas la balise identifiée par orange. Cette méthode accepte 3 arguments. Le premier argument est la nature de l'événement lui-même en tant que chaîne de caractères. Dans ce cas, l'événement c'est clic. Notez bien qu'il ne faut pas mettre le on dans ce cas. Deuxième paramètre, c'est la fonction à exécuter. Il est préférable que ce soit une fonction anonyme de la même manière que la méthode précédente. Donc function. Et on met des accolades pour spécifier le corps de la fonction. Et le troisième argument qui est un booléen qui est par défaut false. Ensuite je vais revenir sur cet argument pour comprendre à quoi ça sert. Bon maintenant ici il suffit de déclarer le code que je souhaite. Par exemple je vais mettre quelque chose du genre alerte Bonjour comme tout à l'heure. Maintenant on exécute pour voir le résultat. Je clique et j'ai toujours bonjour qui s'affiche. Bon, maintenant on va faire le même traitement que tout à l'heure, c'est-à-dire que je vais déclarer sur le même objet le même événement mais avec un traitement différent. Dans ce cas, addEventListener et je mettrai ici bonsoir. Alors là, j'imagine que nous avons deux traitements différents. On va voir est-ce qu'ils seront exécutés tous les deux ou bien seulement le dernier comme c'était le cas pour l'ancienne méthode. Bon, quand je clique, il y a Bonjour qui s'affiche et ensuite Bonsoir. Alors déjà, addEventListener permet de déclarer le même événement plusieurs fois de suite sur le même objet sans que les anciens gestionnaires d'événements soient écrasés. Mais en fait, ce n'est pas le seul avantage puisque la méthode addEventListener va plus loin que ça. Bon, d'ailleurs, si vous avez bien remarqué le code HTML, j'ai 2 divs qui s'imbriquent l'une dans l'autre. J'ai la div jaune incluse dans la div orange D'où le rendu suivant. Nous avons 2 rectangles qui s'imbriquent de cette manière. Maintenant imaginez que j'ai déclaré un gestionnaire d'événements sur la div jaune. Imaginons que c'est le clic. Dans ce cas quand je clique sur la div jaune, j'imagine que j'ai aussi cliqué sur la div orange puisque le parent de la div jaune est la div orange. Et ça c'est tout à fait naturel. Ce genre de situation peut être traité par la méthode addEventListener. Pour mieux comprendre on va mettre le code suivant. Sur la balise orange, on va mettre addEventListener, toujours clic, et au lieu d'afficher bonjour, on va afficher carrément l'identifiant de la div concernée, à savoir le message orange. Et de préférence, on va afficher ça dans la console. On va mettre dans console.log. Bon, je peux mettre directement orange, ou bien je peux le récupérer dynamiquement de cette manière. this, ça veut dire l'objet courant,.getAttribute Ça veut dire que je vais récupérer la valeur de l'attribut ID dans ce cas. Donc setAttribute permet de spécifier un attribut et getAttribute permet de lire la valeur de l'attribut. L'attribut concerné dans ce cas c'est ID. Alors maintenant quand j'exécute, j'affiche la console. Quand je clique sur la div orange, on voit bien que le message orange est affiché ici. Bon, je vais agrandir un petit peu pour mieux voir ça. Voilà. Et quand je clique sur la div jaune, j'ai encore orange qui s'écrit. Voilà. Donc de la même manière, c'est-à-dire que l'événement est détecté que je clique directement sur la div orange ou bien sur la div jaune, puisque la div jaune est incluse dans la div orange. Ils se partagent le même espace en quelque sorte. Bon, maintenant je vais déclarer le même gestionnaire d'événements, mais maintenant sur la div jaune. Alors là, je mettrai jaune. Voilà. Bon, le code restera le même. Et maintenant je vais exécuter pour voir le résultat. Quand je clique sur la div orange, alors forcément le message c'est orange. Et quand je clique sur la div jaune, je vois bien que j'ai 2 messages. J'ai le message jaune suivi du message orange. C'est-à-dire le premier événement clic qui a été détecté, il a été détecté sur la div jaune. Et ensuite le clic sur la div orange est détecté à son tour. On constate alors que les événements se propagent dans le document. En fait, il existe bien un flux pour les événements et il y en a 2 types. Il y a un flux descendant, c'est-à-dire que les événements se propagent de haut en bas, à savoir ça va commencer de la balise HTML et ça descend jusqu'à atteindre la dernière cible, ça veut dire la cible la plus profonde du document concerné par l'événement. On appelle ce flux la capture. Et ensuite, l'événement remonte à partir de l'objet courant, c'est-à-dire l'objet le plus profond concerné par l'événement, il remonte jusqu'à la balise HTML Ce sens inverse est appelé bouillonnement ou bien babbling. Alors là, on imagine que quand j'ai cliqué sur la div jaune, l'événement s'est propagé, il a traversé la div orange, mais il n'a pas été pris en compte. Par contre, quand il a atteint la div jaune, dans ce cas, il a été pris en considération et j'ai le message jaune qui s'est affiché. Ensuite, l'événement remonte et il a été encore détecté sur la div orange. Alors on imagine que le flux par défaut des événements JavaScript, c'est le flux bouillonnant. C'est-à-dire que quand l'événement descend, il sera pas pris en considération, mais quand il va remonter, dans ce cas, le gestionnaire d'événements sera pris en charge par le navigateur. On peut changer ce comportement par défaut, et ça c'est le rôle de l'argument booléen. Ici, avec la valeur false, qui est la valeur par défaut d'ailleurs, le flux d'événements c'est le bouillonnement. Maintenant, si je mets ici true, alors dans ce cas capture devient le flux par défaut de propagation des événements. Regardons maintenant qu'est-ce qui va se passer. Alors souvenez-vous bien que quand j'ai cliqué sur la div jaune, j'ai affiché jaune puis orange. Maintenant j'actualise, je reclique. Alors là vous avez remarqué qu'il y a une permutation, donc il y a orange au début puis jaune. Et ça, ça constitue un des avantages clés de la méthode addEventListener. En fait, en plus de permettre de déclarer le même gestionnaire d'événements plusieurs fois sur le même objet, il permet aussi de prendre en considération le flux capture ou bien le flux bouillonnement au choix, selon les besoins. Du programmeur. Alors récapitulons. Afin de déclarer un gestionnaire d'événements, vous avez le choix entre 3 méthodes différentes. Soit déclarer l'événement onlocal sur la balise courante en tant qu'attribut HTML et vous lui associez une fonction JavaScript. Ou bien vous déclarez le gestionnaire d'événements en tant qu'attribut JavaScript de l'objet concerné. Dans ce cas par exemple document.getElementById orange.onclick ou bien onMouseover. Il faut juste vérifier la casse de telle sorte à ce que tout soit écrit en minuscule. Je parle bien de l'attribut. Et la troisième et la meilleure méthode, c'est l'utilisation de l'écouteur de l'événement ou bien addEventListener en tant que méthode qui peut accepter 3 arguments: l'événement lui-même sans le on, la fonction anonyme qui contient le traitement souhaité et le troisième argument qui est un booléen qui vaut par défaut la valeur false pour dire que c'est le flux bouillonnement qui est pris en considération par défaut. Et si vous voulez changer le sens de récupération des événements, dans ce cas vous mettez true pour dire que c'est la capture. Merci pour votre attention et à la vidéo prochaine.
More from Yamossoun

Algorithme de calcule de la racine carrée par dichotomie #dichotomy #squareroot #algorithm









