09

DOM Manipulation

Sélection, Modification & Performance

Le DOM (Document Object Model) est l'interface JavaScript pour manipuler le HTML. Maîtriser le DOM est essentiel pour créer des interfaces dynamiques.

🎯 Méthodes de Sélection

querySelector()
// Premier élément trouvé
const btn = document.querySelector('.btn');
const title = document.querySelector('#title');

// Sélecteur CSS complexe
const first = document.querySelector('ul > li:first-child');
⚡ Rapide
querySelectorAll()
// Tous les éléments (NodeList)
const items = document.querySelectorAll('.item');

// ⚠️ Pas un Array ! Convertir :
const arr = Array.from(items);
arr.forEach(item => {...});
⚡ Rapide
getElementById()
// Par ID (sans #)
const el = document.getElementById('myId');

// ✅ Plus rapide que querySelector
// ❌ Moins flexible
⚡⚡ Très rapide
Traversal (Navigation)
const el = document.querySelector('.item');

el.parentElement;     // Parent
el.children;          // Enfants
el.nextElementSibling; // Suivant
el.previousElementSibling; // Précédent

🔧 Manipulation du DOM

createElement()
const div = document.createElement('div');
div.className = 'box';
div.textContent = 'Hello';

document.body.appendChild(div);
classList API
const el = document.querySelector('.box');

el.classList.add('active');
el.classList.remove('hidden');
el.classList.toggle('dark');
el.classList.contains('active'); // true
Attributes
const img = document.querySelector('img');

img.getAttribute('src');
img.setAttribute('alt', 'Photo');
img.dataset.userId = '123'; // data-user-id

// Accès direct
img.src = 'new.jpg';
innerHTML vs textContent
const div = document.querySelector('div');

// ⚠️ innerHTML : Parse HTML (XSS risk)
div.innerHTML = 'Bold';

// ✅ textContent : Texte brut (safe)
div.textContent = 'Plain text';

⚡ Optimisation Performance

❌ Lent (Reflow à chaque itération)
// ❌ Mauvais : 1000 reflows
for (let i = 0; i < 1000; i++) {
    const div = document.createElement('div');
    div.textContent = i;
    document.body.appendChild(div);
}

// Chaque appendChild déclenche
// un recalcul du layout !
✅ Rapide (1 seul reflow)
// ✅ Bon : DocumentFragment
const fragment = document.createDocumentFragment();

for (let i = 0; i < 1000; i++) {
    const div = document.createElement('div');
    div.textContent = i;
    fragment.appendChild(div);
}

document.body.appendChild(fragment);
// 1 seul reflow !
// Autres optimisations

// 1. Batch les modifications de style
el.style.cssText = 'width: 100px; height: 100px; background: red;';
// Mieux que 3 lignes séparées

// 2. Cache les sélections
const items = document.querySelectorAll('.item'); // 1 fois
items.forEach(item => item.classList.add('active'));
// Pas de querySelector dans la boucle !

// 3. Utilise classList au lieu de className
el.classList.add('active'); // ✅
el.className += ' active';  // ❌ (remplace tout)

// 4. Event Delegation (voir module Events)
document.addEventListener('click', e => {
    if (e.target.matches('.btn')) {
        // Handle click
    }
});

🏗️ DOM Builder Interactif

Créez des éléments dynamiquement et voyez le résultat.

+ Div
+ Paragraph
+ Button
+ Input
Toggle Class
🗑️ Clear
Cliquez sur les boutons pour construire
Code généré...
Best Practice : Utilisez DocumentFragment pour les insertions multiples. Préférez textContent à innerHTML pour éviter les failles XSS. Cachez les sélections DOM hors des boucles.
← Objects Suivant: Events →