Un ordinateur portable sur un bureau émettant une lumière bleue, créant une ambiance moderne et technologique.

Ecouter les événements du DOM avec addEventListener

Mis à jour le

Comment vos pages réagissent-elles lorsque l'utilisateur clique, appuie sur une touche ou tape du texte ? Grâce à addEventListener, vous pouvez non seulement capter ces interactions, mais aussi personnaliser les réponses de votre page en fonction de l'action de l'utilisateur.

Cette méthode permet d'écouter une grande variété d'événements tels que les clics, les saisies clavier, les mouvements de souris, ou encore les interactions tactiles sur les appareils mobiles. En maîtrisant addEventListener, vous avez le contrôle total sur la manière dont votre application interagit avec ses utilisateurs, rendant vos pages plus dynamiques et réactives.

Syntaxe de base

La méthode addEventListener est utilisée pour attacher une fonction à un événement spécifique sur un élément DOM. Voici la syntaxe de base :

element.addEventListener(type, listener);
  • - element : l'élément du DOM ciblé.
  • - type : le type d'événement à écouter, comme click, keydown, ou submit.
  • - listener : la fonction de rappel (callback) qui sera exécutée lorsque l'événement se produit.

Voici un exemple simple qui réagit à un clic sur un bouton en affichant un message dans la console :

// Sélectionner le bouton
const button = document.querySelector('#myButton');

// Ajouter un écouteur d'événement pour le clic
button.addEventListener('click', () => {
    console.log('Le bouton a été cliqué !');
});

Cet exemple illustre comment un bouton avec l'identifiant myButton peut déclencher une action lorsque l'utilisateur clique dessus. Ce mécanisme est extensible pour des interactions plus complexes, comme la validation de formulaires ou les animations.

Fonctionnement étape par étape

  1. Sélection de l'élément DOM cible : Identifiez l'élément sur lequel vous souhaitez écouter un événement. Cela peut se faire à l'aide de méthodes comme document.querySelector ou getElementById.
  2. Ajout d'un écouteur d'événement : Appelez la méthode addEventListener sur l'élément sélectionné.
  3. Spécification du type d'événement : Indiquez le type d'événement à écouter, comme click, keydown, etc.
  4. Définition de la fonction de callback : Fournissez une fonction (appelée "callback") qui sera exécutée lorsque l'événement se produit.
  5. Attente de l'événement : Une fois configuré, le navigateur attend que l'utilisateur déclenche l'événement spécifié.
  6. Exécution de la fonction de callback : Lorsque l'événement se produit, la fonction de callback est exécutée avec des informations pertinentes sur l'événement.
  7. Retour à l'état d'écoute : Après l'exécution de la fonction, l'écoute continue pour les futurs événements, à moins qu'elle ne soit explicitement supprimée.

Types d'éléments ciblés

La méthode addEventListener peut être utilisée sur une grande variété d'éléments pour capturer des événements spécifiques. Cela permet de gérer des interactions à différents niveaux de votre page web, qu'il s'agisse de comportements globaux ou d'interactions ciblées avec des éléments spécifiques.

1. window (Fenêtre globale)

L'objet window est utilisé pour gérer des événements globaux liés à la fenêtre, comme le redimensionnement ou le défilement. Ces événements affectent la vue globale de la page.

// Écouter l'événement de redimensionnement de la fenêtre
window.addEventListener('resize', () => {
    console.log('La fenêtre a été redimensionnée.');
});

2. document (Document entier)

L'objet document permet d'écouter des événements qui concernent le document entier, comme DOMContentLoaded, qui est déclenché lorsque le contenu HTML a été complètement chargé et analysé.

// Écouter l'événement DOMContentLoaded
document.addEventListener('DOMContentLoaded', () => {
    console.log('Le contenu du DOM est entièrement chargé.');
});

3. Éléments DOM spécifiques

Vous pouvez cibler des éléments spécifiques comme des champs de texte, des images ou des listes déroulantes. Voici un exemple avec un champ de saisie qui détecte lorsqu'un utilisateur tape un texte :

// Cibler un champ de saisie et écouter l'événement "input"
const inputField = document.querySelector('#username');
inputField.addEventListener('input', (event) => {
    console.log(`Vous avez saisi : ${event.target.value}`);
});

Types d'événements courants

Événements liés aux clics et soumissions

click : Cet événement se produit lorsqu'un utilisateur clique sur un élément. C'est l'un des événements les plus utilisés pour gérer les interactions utilisateur.

submit : Cet événement est déclenché lorsqu'un utilisateur soumet un formulaire, ce qui permet de valider et de traiter les données saisies.

Événements liés au clavier

Les interactions au clavier sont détectées grâce à ces événements : keydown (lorsqu'une touche est enfoncée), keyup (lorsqu'une touche est relâchée) et keypress (lorsqu'une touche est pressée, bien que cet événement soit souvent remplacé par keydown pour des raisons de compatibilité).

Événements liés à la souris

Ces événements permettent de gérer les interactions liées au curseur de la souris : mouseover (lorsque la souris survole un élément), mouseout (lorsque la souris quitte un élément), et mousemove (lorsque la souris se déplace au-dessus d'un élément).

Événements liés au chargement

L'événement load est déclenché une fois que toutes les ressources d'une page, y compris ses dépendances, ont terminé de se charger.

Événements liés au focus et aux formulaires

focus et blur : Ces événements se produisent lorsqu'un élément interactif, tel qu'un champ de formulaire, reçoit ou perd le focus respectivement.

change : Cet événement est utilisé pour détecter les modifications de valeur dans les éléments de formulaire tels que les champs de texte ou les listes déroulantes.

Événements de défilement et tactiles

scroll : Cet événement est déclenché lorsqu'un utilisateur fait défiler un élément. Il est souvent utilisé pour ajouter des animations ou charger du contenu supplémentaire.

touchstart, touchend et touchmove : Ces événements sont spécifiques aux appareils tactiles et permettent de gérer les appuis, les déplacements ou les gestes effectués sur un écran tactile.

Exemples pratiques

1. Changer la couleur d'un élément au survol

Cet exemple montre comment changer la couleur de fond d'un élément lorsqu'on le survole avec la souris. Cela peut être utile pour ajouter des effets visuels sur des éléments interactifs comme des cartes ou des boutons.

const card = document.getElementById('card');

function changeColorOnHover() {
    this.style.backgroundColor = 'lightblue';
}

card.addEventListener('mouseover', changeColorOnHover);
card.addEventListener('mouseout', function() {
    this.style.backgroundColor = ''; // Réinitialiser la couleur
});

2. Formulaire avec validation d'email

Cet exemple montre comment valider un formulaire avant de le soumettre. L'adresse e-mail est vérifiée pour s'assurer qu'elle contient bien un "@" avant de permettre la soumission du formulaire.

const form = document.getElementById('form');

form.addEventListener('submit', function(event) {
    const email = document.getElementById('email').value;
    if (!email.includes('@')) {
        event.preventDefault(); // Empêcher la soumission du formulaire
        alert('Veuillez entrer une adresse email valide');
    }
});

3. Navigation par clavier

Ce code permet de gérer la navigation sur une page à l'aide des touches fléchées du clavier. Si l'utilisateur appuie sur la touche "flèche droite", la page suivante sera chargée, et "flèche gauche" retournera à la page précédente.

document.addEventListener('keydown', function(event) {
    if (event.key === 'ArrowRight') {
        // Code pour naviguer vers la page suivante
    } else if (event.key === 'ArrowLeft') {
        // Code pour naviguer vers la page précédente
    }
});

Options avancées de addEventListener

addEventListener accepte un troisième argument, un objet d'options, qui permet de modifier certains comportements par défaut de l'écouteur d'événements. Voyons les trois options les plus courantes :

1. capture

Par défaut, les événements sont traités dans l'ordre de propagation classique, appelé "bubbling", où l'événement se propage d'un élément enfant vers son parent. Si vous définissez capture sur true, l'événement sera capturé pendant la phase de capture, c'est-à-dire avant qu'il n'atteigne l'élément cible. Cela peut être utile si vous voulez intercepter un événement avant qu'il n'atteigne un élément spécifique.

2. once

L'option once permet d'exécuter l'écouteur d'événements une seule fois. Dès que l'événement est déclenché, l'écouteur est automatiquement supprimé. Cela est utile, par exemple, pour des événements temporaires ou des interactions qui ne nécessitent qu'une réponse unique, comme un message d'alerte ou une animation.

3. passive

L'option passive est principalement utilisée pour améliorer les performances, notamment sur des événements comme touchmove ou wheel. En la définissant sur true, vous indiquez au navigateur que l'écouteur ne va pas appeler preventDefault(), ce qui permet au navigateur d'optimiser le défilement et d'améliorer la fluidité des interactions, sans attendre le traitement de l'événement.

Voici un exemple d'utilisation des trois options :

element.addEventListener('click', function() {
    console.log('Événement cliqué');
}, {
    capture: true,  // Capture l'événement avant qu'il n'atteigne l'élément cible
    once: true,     // L'écouteur sera supprimé après le premier déclenchement
    passive: true   // Améliore la performance sans appeler preventDefault()
});

Assurer l'accessibilité

Lorsque vous utilisez addEventListener pour ajouter des événements interactifs, il est important de prendre en compte l'accessibilité pour que tous les utilisateurs, y compris ceux qui utilisent un clavier ou des technologies d'assistance, puissent interagir avec votre site.

  • Assurez-vous que les fonctionnalités sont accessibles au clavier. Par exemple, si vous avez des boutons ou des éléments interactifs personnalisés, vous devez gérer les événements au clavier (comme Enter et Space) en plus du clic souris.
  • Évitez de surcharger la touche Tab pour la navigation afin de ne pas nuire à l'ordre de tabulation des éléments.
  • Utilisez les rôles ARIA appropriés pour informer les utilisateurs des technologies d'assistance (comme les lecteurs d'écran) sur les éléments interactifs.
  • Testez votre site avec des lecteurs d'écran et autres outils d'accessibilité pour vérifier que l'interaction avec les événements est bien interprétée.

Prenons un exemple d'élément div personnalisé en bouton, afin de montrer comment ajouter une prise en charge des événements au clavier pour les utilisateurs qui ne peuvent pas ou ne veulent pas utiliser la souris.

const divBouton = document.getElementById('monDivBouton');

// Action au clic
divBouton.addEventListener('click', function() {
    console.log('Le bouton div a été cliqué');
});

// Action au clavier (pour les utilisateurs qui naviguent au clavier)
divBouton.addEventListener('keydown', function(event) {
    if (event.key === 'Enter' || event.key === ' ') {
        console.log('Le bouton div a été activé par le clavier');
    }
});

Dans cet exemple, la div n'est pas un élément interactif par défaut. Cependant, en ajoutant les événements click et keydown, vous permettez aux utilisateurs de déclencher l'action à la fois en cliquant et en appuyant sur les touches Enter ou Space (les touches standard pour activer les éléments interactifs au clavier).

Comparaison avec d'autres méthodes

Contrairement aux attributs HTML on* (comme onclick) ou à la propriété DOM onclick, addEventListener offre une approche plus flexible de la gestion des événements.

// Ancien système (onclick)
bouton.onclick = function() { 
console.log('Un seul comportement possible'); 
};

// Avec addEventListener
bouton.addEventListener('click', function() { 
console.log('Premier effet'); 
});
bouton.addEventListener('click', function() { 
console.log('Deuxième effet'); 
});
// Les deux effets sont déclenchés

Les avantages clés de addEventListener incluent :

  • L'ajout de plusieurs écouteurs sur un même événement, chacun étant exécuté
  • Un contrôle fin des interactions avec des options avancées
  • Une séparation claire entre la structure HTML et la logique JavaScript
  • La possibilité de facilement ajouter ou supprimer des écouteurs d'événements

Bonnes pratiques et pièges à éviter

Lorsque vous travaillez avec addEventListener, il est important de suivre certaines bonnes pratiques pour assurer une gestion efficace et sans erreur des événements. Voici quelques conseils pour éviter les pièges courants et améliorer la performance et la maintenabilité de votre code.

1. Utiliser removeEventListener pour éviter les fuites mémoire

Une des erreurs fréquentes est d'oublier de retirer un écouteur d'événements lorsque l'élément n'est plus nécessaire. En ne supprimant pas un écouteur d'événements, vous risquez de provoquer des fuites mémoire. Pour éviter cela, utilisez removeEventListener lorsque l'événement n'est plus nécessaire, par exemple lorsqu'un élément est supprimé du DOM ou lorsqu'une page est fermée.

// Exemple de suppression d'un listener
const bouton = document.getElementById('monBouton');
function maFonction() {
    console.log('Bouton cliqué');
}

bouton.addEventListener('click', maFonction);

// Suppression de l'écouteur après un certain temps
setTimeout(() => {
    bouton.removeEventListener('click', maFonction);
}, 5000); // Supprime l'écouteur après 5 secondes

2. Ne pas abuser des écouteurs d'événements

L'ajout excessif de listeners peut nuire aux performances de votre application, surtout si vous écoutez de nombreux événements sur de grands nombres d'éléments. Il est important de ne pas ajouter des écouteurs d'événements sur chaque élément individuellement si cela peut être évité. Par exemple, la délégation d'événements peut permettre de regrouper ces gestionnaires sur un parent, réduisant ainsi le nombre d'écouteurs actifs.

Exemple de délégation d'événements :

// Plutôt que d'ajouter un écouteur sur chaque bouton, on l'ajoute à un parent
const container = document.getElementById('container');
container.addEventListener('click', function(event) {
    if (event.target && event.target.matches('button.classBouton')) {
        console.log('Un bouton a été cliqué');
    }
});

3. La portée (scope) de this dans les fonctions de callback

Un piège classique dans les gestionnaires d'événements est de mal comprendre la portée de this dans les fonctions de callback. Lorsque vous utilisez des fonctions classiques, this fait référence à l'élément sur lequel l'événement a été déclenché. Mais si vous utilisez une fonction fléchée (arrow function), this sera déterminé par la portée lexicale (l'endroit où la fonction est définie), ce qui peut mener à des comportements inattendus.

// Fonction classique (this fait référence à l'élément)
document.getElementById('monElement').addEventListener('click', function() {
    console.log(this);  // this fait référence à l'élément sur lequel l'événement a eu lieu
});

// Fonction fléchée (this fait référence à la portée lexicale)
document.getElementById('monElement').addEventListener('click', () => {
    console.log(this);  // this n'est pas l'élément, mais la portée où la fonction a été définie
});

4. Utiliser des événements adaptés aux besoins

Il est important de choisir l'événement adapté à l'action que vous souhaitez surveiller. Par exemple, pour des interactions tactiles, privilégiez les événements comme touchstart et touchend plutôt que des événements souris comme click. Cela permet de garantir une meilleure expérience utilisateur, en particulier sur les appareils mobiles.

// Exemple d'événement tactile
document.getElementById('monElement').addEventListener('touchstart', function() {
    console.log('Écran touché');
});

En résumé, une gestion judicieuse des événements et une compréhension approfondie de leur fonctionnement permettent de garantir non seulement la performance, mais aussi la maintenabilité et l'accessibilité de vos applications web.

Sources

Mots clés

JavaScript

🚀 Améliorez vos compétences JavaScript et optimisez vos projets web

Vous avez besoin de résoudre des problèmes techniques, d'améliorer la performance de votre code ou d'optimiser la gestion des événements dans vos applications ? Profitez de mon expertise pour vous accompagner dans votre développement.

À partir de 29€, je vous propose une session de coaching personnalisé pour vous aider à maîtriser JavaScript, appliquer les bonnes pratiques et booster l'efficacité de vos projets.

Réservez votre session maintenant