Délégation d'événements dans le navigateur à l'aide de JavaScript vanilla

Une de mes choses préférées dejQueryest (était?) la délégation d'événement. En particulier le.on()méthode.

Nous sélectionnons unDOMélément, puis nous utilisons.on()pour attacher un gestionnaire d'événements qui est exécuté sur un enfant particulier de cet élément.

Pourquoi est-ce utile? Parce que si vous ajoutez des éléments dynamiquement au DOM, un seul écouteur d'événement enregistré via.on()fonctionnera sur tous les enfants, même ceux qui sont ajoutés au DOM après avoir enregistré le gestionnaire d'événements.

Supposons que vous ayez une table. À l'intérieur du tableau, nous avons un ensemble de lignes, et chaque ligne a un bouton avec un gestionnaire de clics.

Vous enregistrez un écouteur d'événements lorsque le DOM se charge:

document.addEventListener('DOMContentLoaded', () => {
  const buttons = document.querySelectorAll('button')

for (const button of buttons) { button.addEventListener(…) } })

Mais si nous ajoutons une nouvelle ligne à la table, nous devons également penser à enregistrer un nouvel écouteur d'événement.

Comment pouvons-nous reproduire la même fonctionnalité en utilisant du JavaScript vanilla?

Nous créons unonfonction qui prend un sélecteur d'encapsuleur, un type d'événement (un'click'string par exemple), une chaîne de sélecteur enfant, qui correspondra aux descendants du sélecteur d'encapsuleur. Dans cette fonction, nous créons d'abord une boucle, et nous ajoutons un écouteur d'événement à chaque élément qui correspond à notre sélecteur de wrapper (afin qu'il puisse s'appliquer à plus d'un sélecteur de wrapper).

Ensuite, si la cible de l'événement correspond à notre sélecteur enfant (troisième paramètre de la fonction), nous appelons la fonction de rappel passée en 4ème paramètre, en passant l'événement:

const on = (selector, eventType, childSelector, eventHandler) => {
  const elements = document.querySelectorAll(selector)
  for (element of elements) {
    element.addEventListener(eventType, eventOnElement => {
      if (eventOnElement.target.matches(childSelector)) {
        eventHandler(eventOnElement)
      }
    })
  }
}

Voici comment nous pouvons invoquer cette fonction:

on('ul', 'click', '.module.complete', event => {
  const item = event.target
  //...your event handler
})

Maintenant, quand nous cliquons sur un élément qui correspond.module.completesous leulselector, le code de la fonction que nous transmettons sera exécuté et nous pouvons extraire la référence de l'élément cliqué deevent.target.

Téléchargez mon gratuitManuel du débutant JavaScript


Plus de tutoriels js: