Section 13.4.3 : DOM manipulation et AJAX
🎯 Objectif pédagogique
Comprendre le DOM (Document Object Model), manipuler dynamiquement les pages web avec JavaScript, et communiquer avec un serveur via AJAX (fetch API).
Le DOM : l'arbre HTML vivant
Le DOM est la représentation en mémoire de votre page HTML sous forme d'arbre d'objets. JavaScript peut lire et modifier cet arbre en temps réel, ce qui permet de créer des interfaces dynamiques sans recharger la page.
Sélectionner des éléments
// Par ID (un seul élément)
const header = document.getElementById('main-header');
// Par sélecteur CSS (premier match)
const btn = document.querySelector('.btn-primary');
const nav = document.querySelector('nav.main-nav');
// Par sélecteur CSS (tous les matchs)
const items = document.querySelectorAll('.list-item');
const links = document.querySelectorAll('a[href^="https"]');
// Itérer sur une NodeList
items.forEach(item => {
console.log(item.textContent);
});
Modifier le DOM
// Texte et HTML
element.textContent = 'Nouveau texte';
element.innerHTML = '<strong>HTML</strong> contenu';
// Classes CSS
element.classList.add('active');
element.classList.remove('hidden');
element.classList.toggle('open');
element.classList.contains('active'); // true/false
// Attributs
element.setAttribute('data-id', '42');
element.getAttribute('href');
element.removeAttribute('disabled');
// Styles inline (éviter si possible)
element.style.color = 'red';
element.style.display = 'none';
// Créer et insérer des éléments
const card = document.createElement('div');
card.classList.add('card');
card.innerHTML = `
<h3>${titre}</h3>
<p>${description}</p>
`;
document.querySelector('.container').appendChild(card);
// Supprimer
element.remove();
Les événements
// Click
const btn = document.querySelector('#submit-btn');
btn.addEventListener('click', (event) => {
event.preventDefault(); // Empêcher le comportement par défaut
console.log('Bouton cliqué !');
});
// Clavier
document.addEventListener('keydown', (event) => {
if (event.key === 'Escape') {
closeModal();
}
});
// Formulaire
const form = document.querySelector('#login-form');
form.addEventListener('submit', (event) => {
event.preventDefault();
const formData = new FormData(form);
const email = formData.get('email');
const password = formData.get('password');
// Envoyer au serveur...
});
// Input en temps réel
const search = document.querySelector('#search-input');
search.addEventListener('input', (event) => {
const query = event.target.value;
filterResults(query);
});
Event Delegation
Au lieu d'attacher un listener à chaque élément d'une liste, attachez-en un seul au parent :
// MAUVAIS : un listener par bouton
document.querySelectorAll('.delete-btn').forEach(btn => {
btn.addEventListener('click', handleDelete);
});
// BON : event delegation
document.querySelector('.items-list').addEventListener('click', (event) => {
if (event.target.matches('.delete-btn')) {
const itemId = event.target.dataset.id;
deleteItem(itemId);
}
});
Fetch API : AJAX moderne
// GET request
const fetchUsers = async () => {
const response = await fetch('https://api.example.com/users');
const users = await response.json();
return users;
};
// POST request
const createUser = async (userData) => {
const response = await fetch('https://api.example.com/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(userData),
});
const newUser = await response.json();
return newUser;
};
// Gestion d erreurs
const fetchData = async (url) => {
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
return await response.json();
} catch (error) {
console.error('Erreur fetch:', error);
}
};
Exemple complet : recherche dynamique
const searchInput = document.querySelector('#search');
const resultsList = document.querySelector('#results');
searchInput.addEventListener('input', async (event) => {
const query = event.target.value.trim();
if (query.length < 2) {
resultsList.innerHTML = '';
return;
}
const response = await fetch(`/api/search?q=${encodeURIComponent(query)}`);
const results = await response.json();
resultsList.innerHTML = results
.map(r => `<li class="result-item">${r.nom}</li>`)
.join('');
});
Pourquoi utiliser event delegation au lieu d'un listener par élément ?
Apprendre l’IA, du premier prompt aux agents