open

La gestion des événements en Javascript

#1 Qu'est-ce qu'un événement ? open

Un événement c'est une sorte de signal qui est envoyé au Javascript par l'interface DOM. Ce signal est envoyé lorsqu'il se passe quelque chose sur un élément de votre document par exemple un clic sur cet élément.

Les éléments d'un document étant en général nombreux, les signaux envoyés par le document sont nombreux et constituent ce que l'on appelle un flux d'événements. Ce flux est envoyé par défaut sans que le programmeur Javascript n'ait besoin de le demander.

Par contre le programmeur a la possibilité d'intercepter un événement faisant partie de ce flux et de programmer un code qui s'exécutera au moment de chacune de ces interceptions. Il le fera en mettant en place un gestionnaire d'événement.

On se rend bien compte ici que l'interface DOM est une interface d'entrée-sortie placée entre le Javascript et le document. D'une part le Javascript peut descendre sur le document pour le modifier. D'autre part l'interface informe le Javascript de ce qui se passe sur le document.

Notons tout de suite que les événements ne sont pas "envoyés" seulement au Javascript. Le CSS reçoit aussi un certain nombre d'événements. Il conviendra de traiter ce qui relève du CSS dans le CSS et ce qui relève du Javascript dans le Javascript. On consacrera un chapitre sur ce point.

#2 La liste des principaux événements open

Evénement Description
load fin de chargement de la page web
click clic sur un élément
dblclick double clic sur un élément
keypress une touche est maintenue enfoncée
keydown une touche est appuyée
keyup une touche est relâchée
mouseenter le curseur entre au dessus d'un élément
mouseleave le curseur quitte l'élément
select sélection d'une option dans un select
change changement de valeur sur un select, un checkbox..
submit soumission d'un formulaire
focus l'élément reçoit le focus
blur l'élément perd le focus

#3 Gérer les événements avec la méthode Javascript element.addEventListener(). open

La méthode addEventListener() appelée par un élément écoute un événement sur cet élément.

Syntaxe

void addEventListener(type,callback[,capture]);

Paramètres

type est une chaîne de caractères représentant le nom de l'événement.

callback est une fonction. Le plus souvent on utilise une fonction anonyme mais vous pouvez très bien mettre le nom d'une fonction (attention sans les parenthèses).

capture est un booléen optionnel. Si il est true c'est dans la phase de capture que sera intercepté l'événement. Si il est false ce sera dans la phase de bouillonnement. Si vous ne le mettez pas il est considéré comme false.

Exemple

Tester le code

#4 Comment se propagent les événements dans l'arbre du document ? open

Les événements se propagent à travers la hiérarchie des objets du document. La propagation se décompose en deux phases :

  1. Une première phase appelée phase de capture dans laquelle les événements partent de la racine du document pour descendre vers l'objet qui a déclenché l'événement.
  2. Une deuxième phase appelée phase de bouillonnement dans laquelle les événements remontent depuis l'objet déclencheur vers la racine du document.

Un même événement peut être intercepté soit pendant la phase de capture soit pendant la phase de bouillonnement. Par défaut il est intercepté pendant la phase de bouillonnement. Un troisième argument peut être ajouté à la méthode addEventLitener pour choisir la phase de capture. On verra un exemple.

Le fait d'intercepter un événement ne stoppe pas sa propagation.

Dans l'exemple ci-dessous cliquez sur le paragraphe. Constatez la propagation de l'événement en phase de bouillonnement vers les éléments parents. D'abord la section puis le body.

Tester le code

Ajoutons un booléen true en troisième argument de addEventListener sur la section. Cliquez sur le paragraphe et vous allez constater que c'est la section qui intercepte l'événement en premier pendant la phase de capture. Les autres suivent en phase de bouillonnement.

Tester le code

#5 L'objet Javascript Event. open

Un objet de constructeur Event peut être passé à la fonction anonyme qui traite l'événement. Ci-dessous les propriétés de cet objet les plus utilisées.

  • type le nom de l'événement
  • target l'objet qui correspond à l'élément sur lequel est déclenché l'événement. On l'appellera dans la suite "élément déclencheur".
  • currentTarget l'objet qui correspond à l'élément sur lequel est monté le gestionnaire. On l'appellera dans la suite "élément intercepteur".

Ci-dessous l'intérêt c'est de cliquer sur le paragraphe pour constater que :

  1. Dans un premier temps c'est le paragraphe qui est à la fois déclencheur et intercepteur.
  2. Puis l'événement est propagé à la section. Dans ce cas l'intercepteur est la section alors que le paragraphe reste le déclencheur.
Tester le code

#6 Comment utiliser this. open

Dans l'exemple ci-dessous this fait référence à l'élément intercepteur quel que soit l'endroit où l'événement est déclenché.

Tester le code

#7 Bloquer la propagation des événements avec la méthode event.stopPropagation() open

L'utilité ici est assez évidente à savoir stopper la propagation d'un événement. Dans l'exemple ci-dessous on stoppe la propagation au niveau du paragraphe.

Tester le code

#8 Bloquer l'éventuel comportement par défaut avec la méthode event.preventDefault() open

Le mieux ici est d'utiliser un lien car un lien a un comportement par défaut. Lorsque l'on clique dessus il nous envoie sur la page spécifiée au niveau de l'attribut href. Ici en plus nous allons monter sur le lien un gestionnaire d'événement qui interceptera le click.

Si on ne fait rien de plus au moment du clic il va se passer deux choses :

  1. Le traitement du click par le gestionnaire.
  2. Suivi du traitement par défaut c'est à dire aller sur la page de wikipedia.

Pour bloquer le traitement par défaut il nous faut utiliser la méthode preventDefault()

Tester le code

#9 Déclencher un événement sur un élément cible open

Dans le programme ci-dessous nous avons deux paragraphes qui sont frères. Si on clique sur un paragraphe l'événement n'est évidemment pas propagé au frère. Justement on va imaginer que c'est notre besoin et on va voir comment le programmer.

Il nous faut un gestionnaire d'événement sur le paragraphe p1 pour intercepter le premier clic. Dans ce gestionnaire on instancie l'objet Event avec la chaîne de caractères 'click'. Puis on "expédie" cet événement vers le deuxième paragraphe p2 avec la méthode dispatchEvent();. Bien sûr on a aussi besoin d'un gestionnaire sur p2 pour intercepter le clic expédié.

Notez bien que c'est sur p2 que se fait l'appel à dispachEvent() alors que c'est lui qui reçoit l'événement. Il faut donc voir ça comme une demande de "dispatch".

Tester le code

#10 D'autres manières "historique" de gérer les événements open

Il est possible d'intercepter les événements au niveau du HTML en utilisant des attributs fait pour cela. On trouve encore des codes dans lesquels cette méthode est utilisée. On va donc la voir.

Le nom des attributs se retrouve en ajoutant le préfixe on devant le nom Javascript de l'événement. Par exemple pour l'événement Javascript click l'attribut HTML s'appelle onclick.

Le return false remplace ici le preventDefault. Ce morceau de code passe à la validation.

Tester le code

Il est bien sûr possible d'accéder à l'attribut HTML depuis le Javascript. Un exemple ci-dessous pour attendre le chargement d'une page web.

Regardez cependant le problème que vous allez avoir si vous décidez d'écrire un deuxième script et d'attendre le chargement de la page avec la même méthode. Le probléme vient du fait que la propriété onload est affectée une deuxième fois et par conséquent seul le deuxième code est exécuté. Je vous laisse vérifier cela sur cet exemple ici. Par contre vous n'avez par ce problème si vous utilisez addEventListener pour mettre en place vos deux gestionnaires. Vérifier ici.

#11 Gérer les événements en Javascript ou en CSS ? open

Il ne faut pas oublier que le CSS3 est capable lui aussi d'intercepter des événements. Prenons le cas d'un élément qui est survolé par le curseur. On imagine que cet élément doit changer de couleur lorsqu'il est survolé.

Techniquement nous avons deux solutions pour faire cela :

  1. utiliser la pseudo-classe :hover de la feuille de style CSS.
  2. utiliser des gestionnaires d'événements Javascript sur les événements mousehover et mouseout.

Dans ce cas qui relève de la présentation du document on laissera faire le CSS.