addEventListener : écouter les actions
Les événements sont le cœur de l'interactivité. Quand l'utilisateur clique, tape, défile : JavaScript peut réagir.
const bouton = document.querySelector("#monBouton");
bouton.addEventListener("click", function() {
alert("Vous avez cliqué !");
});
La méthode addEventListener prend deux arguments :
- Le type d'événement : "click", "submit", "input", "keydown"...
- La fonction handler : ce qui se passe quand l'événement survient
Événements courants
click: clic sourissubmit: soumission d'un formulaireinput: saisie dans un champ (en temps réel)keydown: touche enfoncéemouseover/mouseout: survol sourischange: valeur d'un champ modifiée (quand il perd le focus)
Ce ne sont que les plus courants : il existe des dizaines de types d'événements (clavier, souris, tactile, glisser-déposer, formulaire, média, défilement...). Pour la liste complète, garde ces deux références sous la main :
- Référence des événements sur W3Schools : tous les types, classés par catégorie, avec des exemples.
- Référence des événements sur MDN : la doc de référence, au plus près de la norme (la source que suivent les navigateurs).
L'objet event
Un détail a pu te surprendre : nos fonctions reçoivent un paramètre event qu'on n'a jamais demandé. D'où sort-il ?
La clé, c'est de comprendre que ce n'est pas toi qui appelles ta fonction. Avec addEventListener, tu te contentes de confier ta fonction au navigateur : « quand on cliquera, exécute celle-ci ». C'est ensuite le navigateur qui l'appelle, au moment du clic. Et quand il l'appelle, il en profite pour lui passer un objet event en premier argument, qui décrit ce qui vient de se passer : le type d'action, l'élément visé, la touche pressée, la position du clic...
Autrement dit, l'argument arrive tout seul parce que l'appelant, c'est le navigateur, pas toi. Toi, tu choisis juste son nom (event, e, ce que tu veux) : ce qui compte, c'est sa place, le premier paramètre.
event. Voilà pourquoi tu reçois un argument sans l'avoir demandé.Chaque handler reçoit donc cet objet. Voici comment s'en servir :
document.querySelector("form").addEventListener("submit", function(event) {
event.preventDefault(); // empêche le rechargement de la page
const input = document.querySelector("#email");
console.log("Email :", input.value);
});
document.addEventListener("keydown", function(event) {
console.log("Touche :", event.key); // "Enter", "Escape", "a"...
});
event.preventDefault() est indispensable pour les formulaires : sans ça, la page se recharge et tu perds tout.
Délégation d'événements
Au lieu d'ajouter un événement sur chaque élément, tu l'ajoutes sur le parent et tu vérifies quel enfant a été cliqué :
Un <ul> contient plusieurs <li>. On attache UN SEUL addEventListener("click", ...) sur le <ul>. Avant de dérouler : si l'utilisateur clique sur un <li> enfant, le listener posé sur le <ul> parent se déclenchera-t-il ? Et dans le handler, à quoi correspondent event.target et event.currentTarget ?
Voir la réponse
Oui, le listener du <ul> se déclenche. Quand on clique sur un <li>, l'événement remonte de l'élément cliqué vers ses ancêtres : c'est la propagation par remontée (event bubbling). Le <ul> parent reçoit donc l'événement. Dans le handler : event.target est l'élément réellement cliqué (le <li> précis), tandis que event.currentTarget est l'élément qui porte le listener (le <ul>). C'est le principe de la délégation d'événements : un seul écouteur sur le parent gère tous les enfants, y compris ceux ajoutés dynamiquement plus tard.
document.querySelector("#liste").addEventListener("click", function(event) {
if (event.target.tagName === "LI") {
event.target.classList.toggle("fait");
}
});
Avantage : ça fonctionne même pour les éléments ajoutés dynamiquement après le chargement de la page.
addEventListener — listening to actions
Events are the heart of interactivity. When a user clicks, types, scrolls — JavaScript can react.
const button = document.querySelector("#myButton");
button.addEventListener("click", function() {
alert("You clicked!");
});
The addEventListener method takes two arguments:
- The event type: "click", "submit", "input", "keydown"...
- The handler function: what happens when the event occurs
Common events
click— mouse clicksubmit— form submissioninput— typing in a field (real-time)keydown— key pressedmouseover/mouseout— mouse hoverchange— field value changed (when it loses focus)
These are just the most common ones: there are dozens of event types (keyboard, mouse, touch, drag & drop, form, media, scroll...). For the full list, keep these two references handy:
- Events reference on W3Schools — all types, sorted by category, with examples.
- Events reference on MDN — the reference docs, closest to the standard (the source browsers follow).
The event object
One detail may have surprised you: our functions receive an event parameter we never asked for. Where does it come from?
The key is to realize that you are not the one calling your function. With addEventListener, you simply hand your function to the browser: "when a click happens, run this one". It's then the browser that calls it, at the moment of the click. And when it does, it takes the opportunity to pass it an event object as the first argument, describing what just happened: the action type, the target element, the key pressed, the click position...
In other words, the argument shows up on its own because the caller is the browser, not you. You just pick its name (event, e, whatever): what matters is its position, the first parameter.
event object. That's why you receive an argument you never asked for.So every handler receives this object. Here's how to use it:
document.querySelector("form").addEventListener("submit", function(event) {
event.preventDefault(); // prevents page reload
const input = document.querySelector("#email");
console.log("Email:", input.value);
});
document.addEventListener("keydown", function(event) {
console.log("Key:", event.key); // "Enter", "Escape", "a"...
});
event.preventDefault() is essential for forms — without it, the page reloads and you lose everything.
Event delegation
Instead of adding an event on each element, you add it on the parent and check which child was clicked:
A <ul> contains several <li> items. A single addEventListener("click", ...) is attached to the <ul>. Before scrolling down: if the user clicks on a child <li>, will the listener placed on the <ul> parent fire? And in the handler, what do event.target and event.currentTarget refer to?
See the answer
Yes, the <ul> listener fires. When you click on a <li>, the event travels up from the clicked element to its ancestors: this is event bubbling. The <ul> parent therefore receives the event. In the handler: event.target is the element actually clicked (the specific <li>), while event.currentTarget is the element that holds the listener (the <ul>). This is the principle of event delegation: a single listener on the parent handles all children, including those added dynamically later.
document.querySelector("#list").addEventListener("click", function(event) {
if (event.target.tagName === "LI") {
event.target.classList.toggle("done");
}
});
Advantage: it works even for elements added dynamically after the page loads.
🎯 Pratique
S'entraîner (clique pour ouvrir) :
✨ Prompt IA
Copiez ce prompt dans Claude ou ChatGPT :
Crée un formulaire de contact HTML avec validation JavaScript en temps réel. Utilise addEventListener sur les champs input et submit. Explique chaque événement utilisé.
💬 Ré-explique sans regarder
Sans relire la réponse de l'IA : sur la soumission d'un formulaire, pourquoi appelle-t-on event.preventDefault(), et que se passe-t-il si on l'oublie ?
submit en envoyant le formulaire et en rechargeant la page. event.preventDefault() annule ce comportement natif pour qu'on gère la soumission en JavaScript (lire les .value, valider, appeler une API). Si on l'oublie : la page se recharge, le code après ne s'exécute pas et tout est perdu.L'IA a oublié event.preventDefault() dans le handler de formulaire. La page se recharge au lieu d'afficher le message. Ajoutez la ligne manquante.
⚖️ Juge le code de l'IA
Tu demandes à l'IA de rendre chaque tâche d'une liste cliquable (clic = barrer). Elle propose ce code. Ton rôle de relecteur : l'accepter tel quel ou le rejeter, et dire pourquoi.
const taches = document.querySelectorAll("#liste li");
taches.forEach(function(li) {
li.addEventListener("click", function() {
li.classList.toggle("fait");
});
});
<li> existant au moment de l'exécution : toute tâche ajoutée ensuite (cas typique d'une todo-list) ne réagira pas au clic. C'est exactement le piège que résout la délégation : un seul addEventListener("click") sur le #liste parent, puis un test sur event.target. Ça couvre les éléments dynamiques et évite des dizaines de listeners.🧠 Rappel libre
Sans remonter dans la leçon : quels sont les deux arguments d'addEventListener, et d'où vient l'objet event que reçoit le handler alors qu'on ne l'a jamais demandé ?
addEventListener prend le type d'événement ("click", "submit", "input"…) et une fonction handler. On ne fait que confier cette fonction au navigateur : ce n'est pas nous qui l'appelons. Au moment de l'action, c'est le navigateur qui l'appelle et lui passe un objet event en premier argument (type, event.target, event.key, position…). Le nom est libre, c'est sa place de premier paramètre qui compte.event.preventDefault() ?Votre page réagit désormais aux clics et aux saisies du visiteur. Reste à la nourrir avec des données venues d'ailleurs. La prochaine leçon va chercher l'information sur le web : Fetch et les API, pour récupérer des données distantes sans jamais recharger la page.
Leçon 7 : Fetch et API →