Document Object Model
Manipuler les pages web dynamiquement
Formation DWWM - 2026
Comprendre le Document Object Model
Le DOM (Document Object Model) est une représentation en arbre de ta page HTML que JavaScript peut manipuler.
Imagine ta page HTML comme une marionnette. Le DOM, c'est l'ensemble des fils qui permettent au marionnettiste (JavaScript) de contrÎler la marionnette : changer sa position, ses couleurs, la faire bouger, réagir aux événements...
Sans le DOM, JavaScript ne pourrait PAS interagir avec ta page !
Le DOM organise ta page en arbre hiérarchique avec des parents, enfants, frÚres...
<!DOCTYPE html>
<html>
<head>
<title>Ma Page</title>
</head>
<body>
<h1>Titre</h1>
<p>Paragraphe</p>
</body>
</html>
Chaque balise HTML = un nĆud (node) dans l'arbre DOM
| Type | Description | Exemple |
|---|---|---|
| Document | Racine de tout | document |
| Element | Balises HTML | <div>, <p>, <h1> |
| Text | Texte dans les balises | Le texte dans <p>Texte</p> |
| Attribute | Attributs des balises | class="...", id="..." |
| Comment | Commentaires HTML | <!-- commentaire --> |
En pratique, on manipule surtout les éléments (balises HTML) !
Accéder aux éléments du DOM
Sélectionne un élément par son attribut id.
<h1 id="titre">Bonjour</h1>
<p id="paragraphe">Ceci est un paragraphe</p>
// Sélectionner l'élément avec id="titre"
const titre = document.getElementById("titre");
console.log(titre); // <h1 id="titre">Bonjour</h1>
// Sélectionner le paragraphe
const para = document.getElementById("paragraphe");
console.log(para); // <p id="paragraphe">...</p>
idnull si l'élément n'existe pasSélectionne tous les éléments ayant une classe spécifique.
<p class="important">Premier paragraphe</p>
<p class="normal">DeuxiĂšme paragraphe</p>
<p class="important">TroisiĂšme paragraphe</p>
// Sélectionner TOUS les éléments avec class="important"
const elements = document.getElementsByClassName("important");
console.log(elements); // HTMLCollection [p.important, p.important]
console.log(elements.length); // 2
// Accéder au premier élément
console.log(elements[0]); // <p class="important">Premier...</p>
// Parcourir tous les éléments
for (let element of elements) {
console.log(element.textContent);
}
â ïž Important : Retourne une HTMLCollection (liste dynamique), pas un tableau ! Convertis-la si besoin : Array.from(elements)
Sélectionne tous les éléments d'un type de balise.
<p>Paragraphe 1</p>
<p>Paragraphe 2</p>
<div>Une div</div>
<p>Paragraphe 3</p>
// Sélectionner TOUS les paragraphes
const paragraphes = document.getElementsByTagName("p");
console.log(paragraphes.length); // 3
// Parcourir
for (let p of paragraphes) {
console.log(p.textContent);
}
// Sélectionner toutes les div
const divs = document.getElementsByTagName("div");
console.log(divs.length); // 1
// Compter tous les liens de la page
const liens = document.getElementsByTagName("a");
console.log(`Il y a ${liens.length} liens sur cette page`);
querySelector utilise la syntaxe CSS pour sélectionner le premier élément qui correspond.
Plus flexible et puissante que les anciennes méthodes.
// Par ID (comme getElementById)
const titre = document.querySelector("#titre");
// Par classe (premier élément avec cette classe)
const important = document.querySelector(".important");
// Par balise (premier élément de ce type)
const premierP = document.querySelector("p");
// Sélecteurs combinés
const lienDansDiv = document.querySelector("div a");
const premierLi = document.querySelector("ul li");
// Sélecteurs complexes
const inputEmail = document.querySelector('input[type="email"]');
const premierEnfant = document.querySelector("ul > li:first-child");
const dernierP = document.querySelector("p:last-of-type");
Syntaxe CSS : Utilise EXACTEMENT la mĂȘme syntaxe que CSS (#id, .classe, balise, etc.)
querySelectorAll sélectionne TOUS les éléments qui correspondent au sélecteur CSS.
// Tous les éléments avec class="important"
const importants = document.querySelectorAll(".important");
console.log(importants); // NodeList [p.important, p.important]
console.log(importants.length); // 2
// Tous les paragraphes
const tousLesP = document.querySelectorAll("p");
// Tous les liens dans une div
const liensDansDiv = document.querySelectorAll("div a");
// Parcourir (NodeList a forEach !)
importants.forEach((element) => {
console.log(element.textContent);
});
// Ou avec for...of
for (let element of importants) {
console.log(element);
}
Retourne 1 seul élément (le premier)
Retourne null si rien trouvé
Retourne TOUS les éléments
Retourne une NodeList (vide si rien)
Comprendre en détail ce qui se passe quand on utilise querySelector.
<div class="container">
<p class="texte">Premier paragraphe</p>
<p class="texte important">DeuxiĂšme paragraphe</p>
<p class="texte">TroisiĂšme paragraphe</p>
</div>
const element = document.querySelector(".texte");
console.log(element);
// <p class="texte">Premier paragraphe</p>
console.log(element.textContent);
// "Premier paragraphe"
// â ïž Les autres <p class="texte"> ne sont PAS sĂ©lectionnĂ©s !
Maintenant avec querySelectorAll, la différence importante.
<div class="container">
<p class="texte">Premier paragraphe</p>
<p class="texte important">DeuxiĂšme paragraphe</p>
<p class="texte">TroisiĂšme paragraphe</p>
</div>
const elements = document.querySelectorAll(".texte");
console.log(elements);
// NodeList(3) [p.texte, p.texte.important, p.texte]
console.log(elements.length); // 3
console.log(elements[0].textContent); // "Premier paragraphe"
console.log(elements[1].textContent); // "DeuxiĂšme paragraphe"
console.log(elements[2].textContent); // "TroisiĂšme paragraphe"
Une NodeList ressemble Ă un tableau, mais ce n'est pas EXACTEMENT un tableau !
Imagine une cagette qui contient plusieurs fruits. C'est comme une NodeList : tu peux compter les fruits (length), prendre un fruit précis (index), et parcourir tous les fruits (forEach), mais tu ne peux pas faire TOUTES les opérations d'un vrai panier (comme map ou filter directement).
| Opération | NodeList | Vrai Tableau |
|---|---|---|
| AccĂšs par index | â
list[0] |
â
arr[0] |
| PropriĂ©tĂ© length | â
list.length |
â
arr.length |
| forEach | â
list.forEach() |
â
arr.forEach() |
| map, filter, reduce | â Pas disponibles | â Disponibles |
const nodeList = document.querySelectorAll(".texte");
// Convertir en tableau
const tableau = Array.from(nodeList);
// Ou avec spread
const tableau2 = [...nodeList];
// Maintenant on peut utiliser map, filter, etc.
const textes = tableau.map(el => el.textContent);
console.log(textes); // ["Premier...", "DeuxiĂšme...", "TroisiĂšme..."]
| Méthode | Retourne | Moderne ? | Utilisation |
|---|---|---|---|
| getElementById | 1 Ă©lĂ©ment | â Ancienne | Rapide pour un ID |
| getElementsByClassName | HTMLCollection | â Ancienne | Plusieurs Ă©lĂ©ments par classe |
| getElementsByTagName | HTMLCollection | â Ancienne | Tous les Ă©lĂ©ments d'un type |
| querySelector | 1 Ă©lĂ©ment | â Moderne | SĂ©lecteur CSS, 1 Ă©lĂ©ment |
| querySelectorAll | NodeList | â Moderne | SĂ©lecteur CSS, tous les Ă©lĂ©ments |
Utilise querySelector et querySelectorAll par défaut ! Plus flexibles et puissantes.
// â
Moderne (recommandé)
const titre = document.querySelector("#titre");
const importants = document.querySelectorAll(".important");
// â Ancien (fonctionne mais moins flexible)
const titre = document.getElementById("titre");
const importants = document.getElementsByClassName("important");
Changer le texte et le HTML
textContent permet de lire ou modifier le texte brut d'un élément.
<h1 id="titre">Ancien titre</h1>
<p id="texte">Ancien paragraphe</p>
const titre = document.querySelector("#titre");
console.log(titre.textContent); // "Ancien titre"
// Changer le texte
titre.textContent = "Nouveau titre";
const para = document.querySelector("#texte");
para.textContent = "Nouveau paragraphe !";
<h1 id="titre">Nouveau titre</h1>
<p id="texte">Nouveau paragraphe !</p>
â ïž Attention : textContent traite tout comme du TEXTE. Si tu mets du HTML, il sera affichĂ© comme du texte brut !
titre.textContent = "<strong>Gras</strong>";
// Affiche : <strong>Gras</strong> (pas en gras !)
Décomposons ce qui se passe étape par étape quand on utilise textContent.
<p id="message">Bonjour tout le monde</p>
const message = document.querySelector("#message");
console.log(message.textContent);
message.textContent = "Nouveau message";
Voyons ce qui arrive si l'élément contient du HTML...
<div id="contenu">
<p>Premier paragraphe</p>
<p>DeuxiĂšme <strong>paragraphe</strong></p>
</div>
const contenu = document.querySelector("#contenu");
console.log(contenu.textContent);
Utilité : Parfait pour récupérer uniquement le contenu textuel sans se soucier de la structure HTML !
innerHTML permet de lire ou modifier le HTML complet d'un élément.
<div id="container">
<p>Ancien contenu</p>
</div>
const container = document.querySelector("#container");
console.log(container.innerHTML);
// "<p>Ancien contenu</p>"
// Remplacer tout le contenu
container.innerHTML = "<h2>Nouveau titre</h2><p>Nouveau texte</p>";
// Ajouter du HTML
container.innerHTML += "<p>Paragraphe ajouté</p>";
<div id="container">
<h2>Nouveau titre</h2>
<p>Nouveau texte</p>
<p>Paragraphe ajouté</p>
</div>
Comprendre ce qui se passe vraiment quand on utilise innerHTML.
<div id="box"><p>Texte original</p></div>
const box = document.querySelector("#box");
console.log(box.innerHTML);
box.innerHTML = "<h2>Titre</h2><p>Nouveau</p>";
â ïž Important : L'ancien <p> a Ă©tĂ© COMPLĂTEMENT supprimĂ© et remplacĂ© !
Voyons en détail ce que fait le navigateur quand on utilise innerHTML.
const div = document.querySelector("#box");
div.innerHTML = "<p class='info'>Hello <strong>World</strong>!</p>";
Tout ça se passe en quelques millisecondes ! Le navigateur est trĂšs rapide, mais c'est quand mĂȘme un processus complexe.
Attention à la différence entre remplacer et ajouter !
<div id="liste">
<p>Item 1</p>
<p>Item 2</p>
</div>
const liste = document.querySelector("#liste");
liste.innerHTML = "<p>Item 3</p>";
// Résultat :
// <div id="liste">
// <p>Item 3</p>
// </div>
// â Item 1 et Item 2 sont PERDUS !
const liste = document.querySelector("#liste");
liste.innerHTML += "<p>Item 3</p>";
// Résultat :
// <div id="liste">
// <p>Item 1</p>
// <p>Item 2</p>
// <p>Item 3</p>
// </div>
// â
Item 1 et 2 sont conservés !
Quand tu fais innerHTML +=, le navigateur doit :
C'est lent si répété beaucoup ! PréfÚre appendChild ou append pour ajouter des éléments un par un.
| Caractéristique | textContent | innerHTML |
|---|---|---|
| Contenu | Texte brut uniquement | HTML complet |
| Balises HTML | Affichées comme texte | Interprétées comme HTML |
| SĂ©curitĂ© | â SĂ»r (pas de XSS) | â ïž Risque XSS si input utilisateur |
| Performance | â Plus rapide | â Plus lent (parse HTML) |
| Usage | Texte simple | Structure HTML complexe |
element.textContent = "Bonjour";
// Résultat : Bonjour
element.textContent = "<b>Gras</b>";
// Résultat : <b>Gras</b>
element.innerHTML = "Bonjour";
// Résultat : Bonjour
element.innerHTML = "<b>Gras</b>";
// Résultat : Gras
Conseil : PréfÚre textContent pour du texte simple (plus sûr et rapide). Utilise innerHTML uniquement si tu as besoin de HTML.
CSS dynamique avec JavaScript
La propriété style permet de modifier les styles CSS directement.
<p id="texte">Mon paragraphe</p>
const texte = document.querySelector("#texte");
// Changer la couleur
texte.style.color = "red";
// Changer la taille
texte.style.fontSize = "24px";
// Changer le fond
texte.style.backgroundColor = "yellow";
// Changer plusieurs propriétés
texte.style.padding = "20px";
texte.style.border = "2px solid blue";
texte.style.borderRadius = "10px";
En CSS : background-color
En JavaScript : backgroundColor (camelCase !)
// â ERREUR
element.style.background-color = "red";
// â
CORRECT
element.style.backgroundColor = "red";
| CSS | JavaScript | Exemple |
|---|---|---|
| color | color | element.style.color = "red" |
| background-color | backgroundColor | element.style.backgroundColor = "#fff" |
| font-size | fontSize | element.style.fontSize = "20px" |
| font-weight | fontWeight | element.style.fontWeight = "bold" |
| margin | margin | element.style.margin = "10px" |
| padding | padding | element.style.padding = "20px" |
| border | border | element.style.border = "1px solid black" |
| display | display | element.style.display = "none" |
// Exemple complet
const box = document.querySelector(".box");
box.style.width = "200px";
box.style.height = "200px";
box.style.backgroundColor = "#4caf50";
box.style.color = "white";
box.style.display = "flex";
box.style.justifyContent = "center";
box.style.alignItems = "center";
box.style.borderRadius = "15px";
classList permet d'ajouter, retirer ou basculer des classes CSS (méthode recommandée !).
<p id="texte" class="normal">Mon paragraphe</p>
.normal {
color: black;
}
.important {
color: red;
font-weight: bold;
font-size: 20px;
}
.highlight {
background-color: yellow;
}
const texte = document.querySelector("#texte");
// Ajouter une classe
texte.classList.add("important");
// <p class="normal important">...</p>
// Retirer une classe
texte.classList.remove("normal");
// <p class="important">...</p>
// Basculer (toggle) une classe
texte.classList.toggle("highlight");
// Si la classe existe â la retire
// Si la classe n'existe pas â l'ajoute
// Vérifier si une classe existe
if (texte.classList.contains("important")) {
console.log("Le texte est important");
}
| Méthode | Action | Exemple |
|---|---|---|
| add() | Ajoute une ou plusieurs classes | element.classList.add("classe1", "classe2") |
| remove() | Retire une ou plusieurs classes | element.classList.remove("classe") |
| toggle() | Bascule une classe (ajoute/retire) | element.classList.toggle("actif") |
| contains() | Vérifie si la classe existe | element.classList.contains("classe") |
| replace() | Remplace une classe par une autre | element.classList.replace("old", "new") |
const menu = document.querySelector("#menu");
const bouton = document.querySelector("#toggle-btn");
bouton.addEventListener("click", () => {
menu.classList.toggle("ouvert");
// Si "ouvert" existe â le retire (ferme le menu)
// Si "ouvert" n'existe pas â l'ajoute (ouvre le menu)
});
đĄ Conseil : PrĂ©fĂšre classList Ă la manipulation directe de style. C'est plus propre et maintenable !
Manipuler id, class, href, src...
Lire et modifier n'importe quel attribut HTML.
<img id="photo" src="ancienne.jpg" alt="Photo">
<a id="lien" href="https://example.com">Lien</a>
<input id="email" type="email" placeholder="Email">
const img = document.querySelector("#photo");
console.log(img.getAttribute("src")); // "ancienne.jpg"
console.log(img.getAttribute("alt")); // "Photo"
const lien = document.querySelector("#lien");
console.log(lien.getAttribute("href")); // "https://example.com"
// Changer la source de l'image
img.setAttribute("src", "nouvelle.jpg");
// Changer le lien
lien.setAttribute("href", "https://google.com");
// Changer le placeholder
const input = document.querySelector("#email");
input.setAttribute("placeholder", "Entrez votre email");
Pour les attributs courants, on peut utiliser des propriétés directes (plus simple !).
const img = document.querySelector("img");
img.getAttribute("src");
img.setAttribute("src", "photo.jpg");
const lien = document.querySelector("a");
lien.getAttribute("href");
lien.setAttribute("href", "url.com");
const img = document.querySelector("img");
img.src;
img.src = "photo.jpg";
const lien = document.querySelector("a");
lien.href;
lien.href = "url.com";
// Images
img.src = "nouvelle.jpg";
img.alt = "Description";
// Liens
lien.href = "https://google.com";
lien.target = "_blank";
// Inputs
input.value = "Texte";
input.placeholder = "Entrez...";
input.type = "password";
input.disabled = true;
// ĂlĂ©ments gĂ©nĂ©raux
element.id = "nouvel-id";
element.className = "classe1 classe2";
đĄ Conseil : Utilise les propriĂ©tĂ©s directes quand elles existent. C'est plus simple et lisible !
const input = document.querySelector("#email");
// Vérifier si l'attribut existe
if (input.hasAttribute("required")) {
console.log("Ce champ est obligatoire");
}
if (!input.hasAttribute("disabled")) {
console.log("Ce champ est actif");
}
const input = document.querySelector("#email");
// Supprimer l'attribut disabled
input.removeAttribute("disabled");
// Supprimer le placeholder
input.removeAttribute("placeholder");
const bouton = document.querySelector("#submit-btn");
// Désactiver le bouton
bouton.setAttribute("disabled", "true");
// ou plus simple :
bouton.disabled = true;
// Réactiver le bouton
bouton.removeAttribute("disabled");
// ou :
bouton.disabled = false;
Les attributs data-* permettent de stocker des données personnalisées dans le HTML.
<div id="user" data-id="123" data-role="admin" data-age="25">
Marie Dupont
</div>
<button data-action="delete" data-item-id="42">Supprimer</button>
const user = document.querySelector("#user");
// Lire les données
console.log(user.dataset.id); // "123"
console.log(user.dataset.role); // "admin"
console.log(user.dataset.age); // "25"
// Modifier
user.dataset.age = "26";
// Ajouter
user.dataset.email = "[email protected]";
// Le HTML devient :
// <div data-id="123" data-role="admin" data-age="26" data-email="[email protected]">
HTML : data-nom-compose
JavaScript : dataset.nomCompose (camelCase)
// HTML : data-user-name
// JavaScript : dataset.userName
Modifier la structure du DOM
createElement crée un nouvel élément HTML (mais ne l'ajoute pas encore à la page).
// Créer un nouveau paragraphe
const p = document.createElement("p");
// Créer une div
const div = document.createElement("div");
// Créer un bouton
const bouton = document.createElement("button");
// Ajouter du contenu
p.textContent = "Ceci est un nouveau paragraphe";
// Ajouter des classes
p.classList.add("important", "nouveau");
// Ajouter des styles
p.style.color = "blue";
// Ajouter des attributs
p.setAttribute("data-id", "123");
p.id = "mon-paragraphe";
// Sélectionner le conteneur
const container = document.querySelector("#container");
// Ajouter le paragraphe dedans
container.appendChild(p);
<div id="container">
<p id="mon-paragraphe" class="important nouveau" data-id="123">
Ceci est un nouveau paragraphe
</p>
</div>
const container = document.querySelector("#container");
const p = document.createElement("p");
p.textContent = "Nouveau paragraphe";
container.appendChild(p); // Ajoute Ă la fin
const container = document.querySelector("#container");
// Ajouter plusieurs éléments
const p1 = document.createElement("p");
p1.textContent = "Paragraphe 1";
const p2 = document.createElement("p");
p2.textContent = "Paragraphe 2";
container.append(p1, p2);
// On peut mĂȘme ajouter du texte directement
container.append("Texte simple");
const container = document.querySelector("#container");
const p = document.createElement("p");
p.textContent = "Je serai en premier";
container.prepend(p); // Ajoute au début (avant les autres)
const element = document.querySelector("#element");
const nouveau = document.createElement("p");
nouveau.textContent = "Inséré avant";
element.before(nouveau); // InsÚre AVANT l'élément
const element = document.querySelector("#element");
const nouveau = document.createElement("p");
nouveau.textContent = "Inséré aprÚs";
element.after(nouveau); // InsĂšre APRĂS l'Ă©lĂ©ment
remove() supprime un élément du DOM.
<div id="container">
<p id="p1">Paragraphe 1</p>
<p id="p2">Paragraphe 2</p>
<p id="p3">Paragraphe 3</p>
</div>
// Supprimer un élément spécifique
const p2 = document.querySelector("#p2");
p2.remove();
// Résultat : le paragraphe 2 disparaßt complÚtement
const container = document.querySelector("#container");
// Méthode 1 : Vider le container
container.innerHTML = "";
// Méthode 2 : Supprimer les enfants un par un
while (container.firstChild) {
container.firstChild.remove();
}
â ïž Attention : Une fois supprimĂ©, l'Ă©lĂ©ment est perdu ! Pense Ă le sauvegarder dans une variable si tu veux le rĂ©utiliser.
cloneNode() crée une copie d'un élément.
<div id="original" class="box">
<h2>Titre</h2>
<p>Contenu</p>
</div>
const original = document.querySelector("#original");
// Clone superficiel (sans les enfants)
const clone1 = original.cloneNode(false);
console.log(clone1); // <div id="original" class="box"></div>
// Clone profond (avec tous les enfants)
const clone2 = original.cloneNode(true);
console.log(clone2);
// <div id="original" class="box">
// <h2>Titre</h2>
// <p>Contenu</p>
// </div>
// Modifier le clone
clone2.id = "copie";
clone2.querySelector("h2").textContent = "Copie du titre";
// Ajouter le clone Ă la page
document.body.append(clone2);
đĄ Conseil : Utilise presque toujours cloneNode(true) pour cloner l'Ă©lĂ©ment ET ses enfants.
Réagir aux actions de l'utilisateur
Un événement est une action qui se produit sur la page : clic, frappe clavier, soumission de formulaire...
Un événement, c'est comme un détecteur de mouvement. Tu installes un capteur (addEventListener) sur un élément. Quand quelque chose se passe (clic, survol...), le capteur se déclenche et exécute une action (ta fonction callback).
Comprendre tout le processus depuis l'action de l'utilisateur jusqu'à l'exécution du code.
Tout ça en quelques millisecondes ! Le navigateur est extrĂȘmement rapide.
addEventListener est LA méthode moderne pour gérer les événements.
<button id="btn">Clique-moi</button>
<p id="message"></p>
const bouton = document.querySelector("#btn");
const message = document.querySelector("#message");
// Ăcouter le clic
bouton.addEventListener("click", function() {
message.textContent = "Bouton cliqué !";
});
// Avec arrow function (plus moderne)
bouton.addEventListener("click", () => {
message.textContent = "Bouton cliqué !";
});
1. L'utilisateur clique sur le bouton
2. L'événement "click" est détecté
3. La fonction callback s'exécute
4. Le texte du message change
Décomposons ligne par ligne ce code :
const bouton = document.querySelector("#btn");
bouton.addEventListener("click", () => {
console.log("Cliqué !");
});
Il existe d'autres façons d'ajouter des événements. Pourquoi addEventListener est meilleur ?
// Dans le HTML
<button onclick="faire()">
// Ou en JS
bouton.onclick = function() {
console.log("Cliqué");
};
ProblĂšmes :
// En JavaScript uniquement
bouton.addEventListener("click", () => {
console.log("Cliqué");
});
Avantages :
const bouton = document.querySelector("#btn");
// Premier listener
bouton.addEventListener("click", () => {
console.log("Action 1");
});
// DeuxiĂšme listener (POSSIBLE avec addEventListener !)
bouton.addEventListener("click", () => {
console.log("Action 2");
});
// Les DEUX s'exécutent quand on clique !
// â Impossible avec onclick (Ă©crase le premier)
bouton.onclick = () => console.log("Action 1");
bouton.onclick = () => console.log("Action 2"); // Ăcrase la premiĂšre !
La fonction callback reçoit automatiquement un objet event avec des infos sur l'événement.
const bouton = document.querySelector("#btn");
bouton.addEventListener("click", (event) => {
console.log(event); // Objet MouseEvent complet
// Propriétés utiles
console.log(event.type); // "click"
console.log(event.target); // L'élément cliqué (<button>)
console.log(event.clientX); // Position X du clic
console.log(event.clientY); // Position Y du clic
});
const boutons = document.querySelectorAll(".btn");
boutons.forEach((bouton) => {
bouton.addEventListener("click", (event) => {
// event.target = le bouton précis qui a été cliqué
console.log(event.target.textContent);
event.target.style.backgroundColor = "green";
});
});
const lien = document.querySelector("a");
lien.addEventListener("click", (event) => {
event.preventDefault(); // EmpĂȘche de suivre le lien
console.log("Lien cliqué mais pas suivi !");
});
L'objet event est créé automatiquement par le navigateur et contient TOUTES les informations sur ce qui s'est passé.
Imagine qu'un Ă©vĂ©nement est comme un incident. Le navigateur est comme un policier qui rĂ©dige un rapport complet : qui, quoi, quand, oĂč, comment... L'objet event, c'est ce rapport !
bouton.addEventListener("click", (event) => {
console.log(event);
});
event.target est l'élément EXACT qui a déclenché l'événement.
<div id="container">
<button class="btn">Bouton 1</button>
<button class="btn">Bouton 2</button>
<button class="btn">Bouton 3</button>
</div>
const boutons = document.querySelectorAll(".btn");
boutons.forEach((bouton) => {
bouton.addEventListener("click", (event) => {
console.log(event.target);
console.log(event.target.textContent);
});
});
// Changer la couleur du bouton cliqué
boutons.forEach((bouton) => {
bouton.addEventListener("click", (event) => {
event.target.style.backgroundColor = "green";
});
});
// Afficher quel bouton a été cliqué
boutons.forEach((bouton) => {
bouton.addEventListener("click", (event) => {
alert(`Tu as cliqué sur : ${event.target.textContent}`);
});
});
Certains Ă©lĂ©ments HTML ont des comportements par dĂ©faut. preventDefault() permet de les empĂȘcher.
<a href="https://google.com" id="lien">Cliquez</a>
const lien = document.querySelector("#lien");
lien.addEventListener("click", (event) => {
event.preventDefault(); // â EmpĂȘche de suivre le lien
console.log("Lien cliqué mais on ne va pas sur Google !");
// On peut faire autre chose Ă la place
});
Cas d'usage le PLUS courant : empĂȘcher le rechargement de page lors de la soumission d'un formulaire.
<form id="monForm">
<input type="text" id="nom">
<button type="submit">Envoyer</button>
</form>
const form = document.querySelector("#monForm");
form.addEventListener("submit", () => {
const nom = document.querySelector("#nom").value;
console.log(nom);
});
// â PROBLĂME : La page se recharge immĂ©diatement !
// On ne voit mĂȘme pas le console.log !
form.addEventListener("submit", (event) => {
event.preventDefault(); // â EmpĂȘche le rechargement !
const nom = document.querySelector("#nom").value;
console.log(nom);
// Maintenant on peut traiter les données en JavaScript
// Sans que la page se recharge !
});
â Maintenant : Le formulaire ne se soumet pas, la page ne recharge pas, et tu peux gĂ©rer tout en JavaScript !
| ĂvĂ©nement | Se dĂ©clenche quand... |
|---|---|
| click | Clic simple |
| dblclick | Double-clic |
| mousedown | Bouton de souris enfoncé |
| mouseup | Bouton de souris relùché |
| mouseover | Souris entre dans l'élément |
| mouseout | Souris sort de l'élément |
| mousemove | Souris bouge sur l'élément |
const box = document.querySelector(".box");
// Au survol
box.addEventListener("mouseover", () => {
box.style.backgroundColor = "lightblue";
});
// Quand la souris sort
box.addEventListener("mouseout", () => {
box.style.backgroundColor = "white";
});
// Double-clic
box.addEventListener("dblclick", () => {
console.log("Double-cliqué !");
});
| ĂvĂ©nement | Se dĂ©clenche quand... |
|---|---|
| keydown | Touche enfoncée |
| keyup | Touche relùchée |
| keypress | Touche pressée (déprécié) |
document.addEventListener("keydown", (event) => {
console.log("Touche pressée :", event.key);
// Détecter une touche spécifique
if (event.key === "Enter") {
console.log("Entrée pressée !");
}
if (event.key === "Escape") {
console.log("Ăchap pressĂ©e !");
}
// Avec modificateurs
if (event.ctrlKey && event.key === "s") {
event.preventDefault(); // EmpĂȘche la sauvegarde du navigateur
console.log("Ctrl+S détecté !");
}
});
const input = document.querySelector("#search");
input.addEventListener("keydown", (event) => {
console.log("CaractÚre tapé :", event.key);
if (event.key === "Enter") {
console.log("Recherche lancée !");
}
});
| ĂvĂ©nement | Se dĂ©clenche quand... |
|---|---|
| submit | Formulaire soumis |
| change | Valeur d'input changée (perd le focus) |
| input | Valeur d'input modifiée (en temps réel) |
| focus | ĂlĂ©ment reçoit le focus |
| blur | ĂlĂ©ment perd le focus |
<form id="monForm">
<input type="text" id="nom" placeholder="Nom">
<input type="email" id="email" placeholder="Email">
<button type="submit">Envoyer</button>
</form>
const form = document.querySelector("#monForm");
form.addEventListener("submit", (event) => {
event.preventDefault(); // EmpĂȘche le rechargement de la page
const nom = document.querySelector("#nom").value;
const email = document.querySelector("#email").value;
console.log("Nom :", nom);
console.log("Email :", email);
});
Se déclenche quand la valeur change ET que l'input perd le focus
input.addEventListener("change", () => {
console.log(input.value);
});
// Se déclenche : aprÚs avoir tapé
// ET quitté le champ
Se déclenche à CHAQUE modification (temps réel)
input.addEventListener("input", () => {
console.log(input.value);
});
// Se déclenche : à chaque frappe
// En temps réel !
const textarea = document.querySelector("textarea");
const compteur = document.querySelector("#compteur");
textarea.addEventListener("input", () => {
const longueur = textarea.value.length;
compteur.textContent = `${longueur} caractĂšres`;
});
Récupérer et valider les données
<form id="inscription">
<input type="text" id="nom" name="nom">
<input type="email" id="email" name="email">
<input type="password" id="password" name="password">
<input type="checkbox" id="newsletter" name="newsletter">
<select id="pays" name="pays">
<option value="fr">France</option>
<option value="be">Belgique</option>
</select>
<button type="submit">S'inscrire</button>
</form>
const form = document.querySelector("#inscription");
form.addEventListener("submit", (event) => {
event.preventDefault();
// Récupérer les valeurs
const nom = document.querySelector("#nom").value;
const email = document.querySelector("#email").value;
const password = document.querySelector("#password").value;
// Checkbox (true/false)
const newsletter = document.querySelector("#newsletter").checked;
// Select
const pays = document.querySelector("#pays").value;
console.log({nom, email, password, newsletter, pays});
});
FormData permet de récupérer facilement TOUTES les données d'un formulaire.
form.addEventListener("submit", (event) => {
event.preventDefault();
const nom = document.querySelector("#nom").value;
const email = document.querySelector("#email").value;
// ... rĂ©pĂ©ter pour chaque champ đ°
});
form.addEventListener("submit", (event) => {
event.preventDefault();
// Créer un objet FormData
const formData = new FormData(form);
// Récupérer les valeurs
const nom = formData.get("nom");
const email = formData.get("email");
const password = formData.get("password");
// Ou convertir en objet
const data = Object.fromEntries(formData);
console.log(data);
// {nom: "...", email: "...", password: "..."}
});
đĄ Avantage : FormData rĂ©cupĂšre automatiquement tous les champs qui ont un attribut name !
const form = document.querySelector("#inscription");
form.addEventListener("submit", (event) => {
event.preventDefault();
const nom = document.querySelector("#nom").value;
const email = document.querySelector("#email").value;
const password = document.querySelector("#password").value;
// Validation
let erreurs = [];
if (nom.trim() === "") {
erreurs.push("Le nom est obligatoire");
}
if (email.trim() === "") {
erreurs.push("L'email est obligatoire");
} else if (!email.includes("@")) {
erreurs.push("L'email n'est pas valide");
}
if (password.length < 8) {
erreurs.push("Le mot de passe doit faire au moins 8 caractĂšres");
}
// Afficher les erreurs
if (erreurs.length > 0) {
alert(erreurs.join("\n"));
} else {
console.log("Formulaire valide !");
// Envoyer les données...
}
});
Tout mettre en pratique
<div>
<input type="text" id="nouvelle-tache" placeholder="Nouvelle tĂąche">
<button id="ajouter-btn">Ajouter</button>
</div>
<ul id="liste-taches"></ul>
const input = document.querySelector("#nouvelle-tache");
const bouton = document.querySelector("#ajouter-btn");
const liste = document.querySelector("#liste-taches");
function ajouterTache() {
const texte = input.value.trim();
if (texte === "") {
alert("Entrez une tĂąche !");
return;
}
// Créer le li
const li = document.createElement("li");
li.textContent = texte;
// Créer le bouton supprimer
const btnSuppr = document.createElement("button");
btnSuppr.textContent = "â";
btnSuppr.style.marginLeft = "10px";
// ĂvĂ©nement supprimer
btnSuppr.addEventListener("click", () => {
li.remove();
});
// ĂvĂ©nement marquer comme fait
li.addEventListener("click", () => {
li.style.textDecoration = "line-through";
li.style.opacity = "0.5";
});
// Assembler
li.appendChild(btnSuppr);
liste.appendChild(li);
// Vider l'input
input.value = "";
}
// ĂvĂ©nements
bouton.addEventListener("click", ajouterTache);
input.addEventListener("keydown", (e) => {
if (e.key === "Enter") ajouterTache();
});
<button id="ouvrir-modal">Ouvrir</button>
<div id="modal" style="display: none;">
<div class="modal-content">
<span id="fermer-modal">×</span>
<h2>Titre de la modal</h2>
<p>Contenu de la modal</p>
</div>
</div>
const modal = document.querySelector("#modal");
const btnOuvrir = document.querySelector("#ouvrir-modal");
const btnFermer = document.querySelector("#fermer-modal");
// Ouvrir la modal
btnOuvrir.addEventListener("click", () => {
modal.style.display = "block";
});
// Fermer avec le X
btnFermer.addEventListener("click", () => {
modal.style.display = "none";
});
// Fermer en cliquant à l'extérieur
modal.addEventListener("click", (event) => {
if (event.target === modal) {
modal.style.display = "none";
}
});
// Fermer avec Ăchap
document.addEventListener("keydown", (event) => {
if (event.key === "Escape" && modal.style.display === "block") {
modal.style.display = "none";
}
});
<div>
<button id="moins">-</button>
<span id="compteur">0</span>
<button id="plus">+</button>
<button id="reset">Reset</button>
</div>
const compteurElement = document.querySelector("#compteur");
const btnMoins = document.querySelector("#moins");
const btnPlus = document.querySelector("#plus");
const btnReset = document.querySelector("#reset");
let compteur = 0;
function mettreAJour() {
compteurElement.textContent = compteur;
// Changer la couleur selon la valeur
if (compteur > 0) {
compteurElement.style.color = "green";
} else if (compteur < 0) {
compteurElement.style.color = "red";
} else {
compteurElement.style.color = "black";
}
}
btnPlus.addEventListener("click", () => {
compteur++;
mettreAJour();
});
btnMoins.addEventListener("click", () => {
compteur--;
mettreAJour();
});
btnReset.addEventListener("click", () => {
compteur = 0;
mettreAJour();
});
| Action | Méthode | Exemple |
|---|---|---|
| Sélectionner | querySelector | document.querySelector("#id") |
| Sélectionner tous | querySelectorAll | document.querySelectorAll(".class") |
| Modifier texte | textContent | element.textContent = "texte" |
| Modifier HTML | innerHTML | element.innerHTML = "<p>...</p>" |
| Modifier style | style | element.style.color = "red" |
| Ajouter classe | classList.add | element.classList.add("classe") |
| Créer élément | createElement | document.createElement("div") |
| Ajouter élément | append | parent.append(enfant) |
| Supprimer élément | remove | element.remove() |
| Ăcouter Ă©vĂ©nement | addEventListener | element.addEventListener("click", fn) |
Vous maĂźtrisez maintenant :
đ SĂ©lectionner des Ă©lĂ©ments (querySelector)
âïž Modifier le contenu (textContent, innerHTML)
đš Modifier les styles (style, classList)
đïž CrĂ©er et supprimer des Ă©lĂ©ments
đ±ïž GĂ©rer les Ă©vĂ©nements (addEventListener)
đ Travailler avec les formulaires