Les événements

Programmation web - Client riche

Objectifs

  • Savoir ajouter / supprimer des gestionnaires d'événements sur des éléments du DOM
  • Comprendre comment le navigateur représente un événement
  • Comprendre les différentes phases que traverse un événement
  • Comprendre la délégation d'événements

Un événement : qu'est-ce que c'est ?

Un événement, c'est quand il se passe quelque chose...

... sur un élément

  • click/ mouseover / mouseout /mousemove
  • focus / blur
  • submit
  • keydown / keyup

... sur le document

  • DOMContentLoaded         

... sur le style d'un élément

  • transitionend                     

... sur des requêtes réseau

  • onload, onerror...

Comment réagir à un événement ?

const onClick = () => console.log("You clicked!")

element.addEventListener(
  "click", // Type de l'événement
  onClick // Fonction à exécuter
)

Ajouter un gestionnaire d'événements à un élément du DOM

Pour pouvoir réagir à un événement, il nous faut :

  • un élément sur lequel écouter les événements
  • un type d'événement auquel on veut réagir
  • une fonction qui décrit ce qu'on veut faire lorsque l'événement est déclenché

Exemple : event click

Exemple : plusieurs gestionnaires d'événement sur un élément

Arrêter un gestionnaire d'événements

Arrêter un gestionnaire d'événements (1)

Pour arrêter un gestionnaire d'événements sur un élément, on a besoin de :

  • l'élément sur lequel le gestionnaire est actif
  • le type d'événement pour lequel on veut supprimer un gestionnaire
  • la fonction associée au gestionnaire
const onClick = () => console.log("You clicked!")

element.addEventListener("click", onClick)

element.removeEventListener("click", onClick)

Arrêter un gestionnaire d'événements (2)

Accéder aux propriétés d'un événement avec l'objet Event

L'objet Event

Lorsqu'une fonction associée à un gestionnaire d'événement est exécutée, elle reçoit automatiquement en premier paramètre un objet représentant l'événement déclenché

const element = document.querySelector(".js-element")

const onClick = (event) => {
  console.log(event.type)
  console.log(event.target)
  console.log(event.currentTarget)
  console.log(event.clientX)
  console.log(event.clientY)
}

element.addEventListener("click", onClick)

Exemple : les propriétés de l'objet Event

Empêcher un comportement par défaut avec la méthode preventDefault

Sur certains types d'éléments, le navigateur a un comportement par défaut pour un certain nombre d'événements :

 

  • Click sur un lien : suivre l'URL de l'attribut href
  • Envoi d'un formulaire : suivre l'URL de l'attribut action
  • Appuyer sur une touche lorsque le focus est sur un champ de formulaire : afficher le caractère dans le champ
  • ...

 

Ces comportements peuvent être annulés grâce à la méthode preventDefault de l'objet Event

Exemple : preventDefault lors du click sur un  lien

Exemple : preventDefault lors de l'envoi d'un formulaire

Les phases d'un événement

Bouillonnement (bubbling) (1)

Bouillonnement (bubbling) (2)

target vs currentTarget

capture (1)

capture (2)

La délégation d'événements

La délégation d'événement : quoi, pourquoi ?

Lorsqu'on a beaucoup d'éléments sur lesquels on attache des événements, on a beaucoup de gestionnaires d'événements. On utilise donc beaucoup de mémoire...

 

Lorsque les éléments peuvent être supprimés / ajoutés dynamiquement, il faut gérer l'ajout et la suppression des gestionnaires d'événements, pour ne pas avoir de fuite mémoire...

 

Une solution est rendue possible par le bouillonnement des événements : attacher un gestionnaire sur un élément parent, et réagir aux événements seulement si la target nous intéresse.

Délégation : le "problème"

Délégation : première implémentation

Délégation : implémentation générique

La délégation d'événement est un pattern parfait lorsque :

  • des éléments dynamiques (e.g. qui apparaissent, disparaissent, changent de position...) sont tous contenus dans un même élément
  • l'élément qui contient les autres n'est pas lui-même dynamique

Implémenter la délégation d'événement proprement en gérant tous les cas à la marge peut être fastidieux. ftdomdelegate gère tout ça très bien

Délégation : ftdomdelegate

Récap ! (1)

  • Un événement peut être déclenché sur un élément du DOM (mais pas que)
  • On peut attacher une fonction à un événement grâce à la méthode addEventListener d'un élément
  • On peut arrêter un gestionnaire d'événement grâce à la méthode removeEventListener d'un élément
  • Une fonction attachée à un événement recevra en premier argument un objet représentant l'événement lorsqu'elle est exécutée
  • Cet objet a des propriétés qui dépendent du type d'événement qu'il représente, et des propriétés "fixes"

Récap ! (2)

  • La propriété target permet d'obtenir l'élément sur lequel l'événement a été déclenché
  • La méthode preventDefault permet d'annuler le comportement par défaut du navigateur pour un événement donné sur un type d'élément donné
  • Un événement suit 3 phases : capture (descente du DOM), target (arrivée sur l'élément qui a déclenché l'événement), bubbling (remontée du DOM)
  • Par défaut, addEventListener crée un gestionnaire qui prend en compte les phases target et bubbling
  • Mais on peut forcer addEventListener à prendre en compte la phase de capture

Récap ! (3)

  • La phase de bubbling nous permet de placer un gestionnaire sur un élément parent de l'élément sur lequel on veut réagir à un événement
  • La délégation d'événement permet de n'attacher qu'un seul gestionnaire sur un élément parent plutôt qu'un sur chaque élément enfant
  • La délégation d'événement peut être implémentée à la main, mais  il est plus sage d'utiliser une librairie comme ftdomdelegate qui prend en compte différents cas à la marge

Des questions ?

Programmation web - client riche - Les événements

By Cyrille Perois

Programmation web - client riche - Les événements

  • 934