Section 11.1.13 : JavaScript — DOM et interactivité
🎯 Objectif pédagogique
Manipuler le DOM (Document Object Model) pour modifier dynamiquement le contenu HTML et CSS via JavaScript. Vous serez capable de sélectionner des éléments, modifier leur contenu, changer leur style, et créer des éléments dynamiquement.
Le DOM — Le pont entre JavaScript et HTML
Quand le navigateur charge une page HTML, il crée une représentation en mémoire de tous les éléments : le DOM (Document Object Model). JavaScript peut lire et modifier ce DOM — c'est ainsi que les pages web deviennent interactives.
Analogie de Marc : "Le HTML est le plan de l'appartement. Le DOM est l'appartement construit. JavaScript est le décorateur qui peut déplacer les meubles, changer les couleurs des murs, et ajouter de nouvelles pièces — le tout sans reconstruire l'appartement."
Sélectionner des éléments
// Par ID (un seul élément)
const header = document.getElementById("header");
// Par sélecteur CSS (premier match)
const firstCard = document.querySelector(".card");
// Par sélecteur CSS (tous les matchs)
const allCards = document.querySelectorAll(".card");
// Résultat : NodeList (similaire à un tableau)
console.log(allCards.length); // Nombre de cartes
allCards.forEach(card => \{
console.log(card.textContent);
\});
querySelector > getElementById
document.querySelector() est plus moderne et plus flexible — il utilise les sélecteurs CSS que vous connaissez déjà. querySelector('.card:first-child'), querySelector('[data-id="42"]') sont impossibles avec getElementById.
Modifier le contenu
const title = document.querySelector("h1");
// Modifier le texte
title.textContent = "Nouveau titre"; // Texte brut (sécurisé)
title.innerHTML = "<em>Nouveau</em> titre"; // HTML (attention XSS si données utilisateur)
// Modifier les attributs
const link = document.querySelector("a");
link.href = "https://github.com";
link.target = "_blank";
const img = document.querySelector("img");
img.src = "nouvelle-photo.jpg";
img.alt = "Ma nouvelle photo";
// Modifier les styles
title.style.color = "#0891B2";
title.style.fontSize = "3rem";
title.style.marginBottom = "2rem";
// Ajouter/retirer des classes (meilleure pratique)
title.classList.add("highlighted");
title.classList.remove("hidden");
title.classList.toggle("active"); // Ajoute ou retire selon l'état
Créer et supprimer des éléments
// Créer un élément
const newCard = document.createElement("div");
newCard.className = "card";
newCard.innerHTML = \`
<h3>Nouveau projet</h3>
<p>Description du projet...</p>
\`;
// L'ajouter au DOM
const container = document.querySelector(".cards-grid");
container.appendChild(newCard); // À la fin
container.prepend(newCard); // Au début
container.insertBefore(newCard, container.children[1]); // Après le 1er
// Supprimer
newCard.remove();
// ou depuis le parent :
container.removeChild(newCard);
Exemple complet : liste dynamique
<div id="skill-app">
<h2>Mes compétences</h2>
<ul id="skill-list"></ul>
<input type="text" id="skill-input" placeholder="Nouvelle compétence">
<button id="add-skill">Ajouter</button>
<p id="skill-count">Compétences : 0</p>
</div>
const skillList = document.querySelector("#skill-list");
const skillInput = document.querySelector("#skill-input");
const addButton = document.querySelector("#add-skill");
const skillCount = document.querySelector("#skill-count");
const skills = [];
function addSkill() \{
const value = skillInput.value.trim();
if (!value) return;
skills.push(value);
const li = document.createElement("li");
li.textContent = value;
// Bouton supprimer
const deleteBtn = document.createElement("button");
deleteBtn.textContent = "❌";
deleteBtn.style.marginLeft = "0.5rem";
deleteBtn.addEventListener("click", () => \{
li.remove();
skills.splice(skills.indexOf(value), 1);
updateCount();
\});
li.appendChild(deleteBtn);
skillList.appendChild(li);
skillInput.value = "";
skillInput.focus();
updateCount();
\}
function updateCount() \{
skillCount.textContent = \`Compétences : \$\{skillList.children.length\}\`;
\}
addButton.addEventListener("click", addSkill);
// Aussi ajouter avec la touche Entrée
skillInput.addEventListener("keypress", (e) => \{
if (e.key === "Enter") addSkill();
\});
Data attributes
<div class="card" data-id="42" data-category="tech">
<h3>Mon projet</h3>
</div>
const card = document.querySelector(".card");
console.log(card.dataset.id); // "42"
console.log(card.dataset.category); // "tech"
card.dataset.status = "active"; // Ajoute data-status="active"
🏋️ Exercice pratique (25 minutes)
Ajoutez l'interactivité à votre portfolio :
- →Un bouton qui bascule entre mode clair et sombre
- →Un compteur de vues (simulé) qui s'incrémente au clic
- →Un formulaire qui affiche les données saisies dans la console
// Dark mode toggle
const toggleBtn = document.querySelector("#dark-mode-toggle");
toggleBtn.addEventListener("click", () => \{
document.body.classList.toggle("dark-mode");
const isDark = document.body.classList.contains("dark-mode");
toggleBtn.textContent = isDark ? "☀️ Mode clair" : "🌙 Mode sombre";
\});
Quelle est la différence entre textContent et innerHTML ?
Comment sélectionner tous les éléments avec la classe 'card' ?
Pourquoi préférer classList.add('active') plutôt que element.style.background = 'blue' ?