W3docs

Techniques de manipulation du DOM en JavaScript

Apprenez à manipuler le DOM en JavaScript : créer, insérer, remplacer et supprimer des éléments, puis optimiser avec le batching, les fragments de document et le clonage de nœuds.

La manipulation du DOM (Document Object Model) est un aspect essentiel du développement web qui vous permet de créer des pages dynamiques et interactives en modifiant la structure, le contenu et le style du document depuis JavaScript. Ce guide commence par les techniques fondamentales pour créer, insérer, remplacer et supprimer des éléments, puis aborde les bonnes pratiques et les optimisations de performance — batching, fragments de document et clonage de nœuds — qui permettent de rendre ces changements rapides.

Si vous n'avez pas encore sélectionné d'élément, commencez par sélectionner des éléments DOM. Pour comprendre l'arbre que vous modifiez, consultez la compréhension des nœuds DOM.

Techniques fondamentales de manipulation

Chaque modification du DOM appartient à l'une des quatre catégories suivantes : créer des nœuds, les insérer, les remplacer ou les supprimer.

Créer des éléments

Utilisez document.createElement() pour construire un élément en mémoire, puis définissez son contenu et ses attributs avant de l'insérer dans la page. Un nœud que vous créez n'est pas visible tant qu'il n'est pas rattaché au document.

const card = document.createElement('div');
card.className = 'card';
card.textContent = 'Hello, DOM!';
card.setAttribute('data-role', 'greeting');

console.log(card.outerHTML);
// <div class="card" data-role="greeting">Hello, DOM!</div>

Préférez textContent à innerHTML lorsque vous insérez du texte brut — c'est plus rapide et vous évite le risque de sécurité lié à l'injection de HTML non échappé.

Insérer des éléments

Une fois qu'un élément existe, rattachez-le à l'aide de l'une de ces méthodes :

  • parent.append(node) — ajoute le nœud comme dernier enfant (accepte également des chaînes de caractères).
  • parent.prepend(node) — l'ajoute comme premier enfant.
  • target.before(node) / target.after(node) — insère un frère avant ou après target.
  • parent.appendChild(node) — l'API classique ; ajoute un seul nœud à la fin et le renvoie.
  • parent.insertBefore(node, reference) — insère node avant l'enfant reference.
const list = document.createElement('ul');

const first = document.createElement('li');
first.textContent = 'First';
list.append(first);

const second = document.createElement('li');
second.textContent = 'Second';
list.append(second);

// Put a new item before the first one.
const top = document.createElement('li');
top.textContent = 'Top';
first.before(top);

console.log(list.children.length); // 3
console.log(list.firstElementChild.textContent); // Top

Pour insérer une chaîne HTML à un emplacement précis sans re-analyser tout le parent, utilisez insertAdjacentHTML() :

const wrapper = document.createElement('div');
const box = document.createElement('div');
box.textContent = 'middle';
wrapper.append(box); // box must be in the tree to gain siblings

box.insertAdjacentHTML('beforebegin', '<span>before</span>');
box.insertAdjacentHTML('afterend', '<span>after</span>');

console.log(box.previousElementSibling.textContent); // before
console.log(box.nextElementSibling.textContent);     // after

Remplacer et supprimer des éléments

  • oldNode.replaceWith(newNode) — remplace oldNode par newNode en place.
  • element.remove() — détache l'élément du DOM.
  • parent.replaceChild(newNode, oldNode) et parent.removeChild(child) — les équivalents plus anciens.
const parent = document.createElement('div');
const a = document.createElement('p');
a.textContent = 'old';
parent.append(a);

const b = document.createElement('p');
b.textContent = 'new';
a.replaceWith(b);

console.log(parent.innerHTML); // <p>new</p>

b.remove();
console.log(parent.innerHTML); // (empty)
Info

Les méthodes modernes (append, prepend, before, after, replaceWith, remove) sont plus lisibles que les méthodes héritées appendChild/insertBefore/replaceChild/removeChild et acceptent plusieurs nœuds et chaînes de caractères à la fois. Préférez-les en priorité ; ne revenez à l'API héritée que si vous devez prendre en charge de très anciens navigateurs.

Bonnes pratiques de manipulation du DOM

Minimiser les accès directs au DOM

L'accès au DOM peut être lent car il peut forcer le navigateur à recalculer la mise en page et à repeindre les éléments. Pour minimiser les accès directs au DOM :

  • Regroupez les mises à jour du DOM au lieu d'effectuer de nombreuses petites mises à jour séparées.
  • Utilisez des variables pour stocker les références aux éléments fréquemment consultés.

Optimiser la gestion des événements

Attachez les gestionnaires d'événements de manière efficace :

  • Utilisez la délégation d'événements pour réduire le nombre d'écouteurs d'événements.
  • Évitez d'attacher trop d'écouteurs d'événements directement aux éléments.

Nettoyer les éléments inutilisés

Supprimez les éléments qui ne sont plus nécessaires pour libérer de la mémoire et améliorer les performances :

  • Utilisez les méthodes removeChild ou remove pour supprimer des éléments du DOM.

Minimiser les reflows et les repaints

Que sont les reflows et les repaints ?

  • Les reflows se produisent lorsque la mise en page d'une partie de la page change, obligeant le navigateur à recalculer les positions et les tailles des éléments.
  • Les repaints surviennent lorsque l'apparence visuelle des éléments change sans affecter la mise en page (par exemple, des changements de couleur).

Techniques pour minimiser les reflows et les repaints

Regrouper les modifications

Regroupez plusieurs modifications ensemble pour éviter des reflows et des repaints répétés :

<!DOCTYPE html>
<html>
<head>
    <title>Batching Changes</title>
</head>
<body>
    <div id="content">Original Content</div>
    <button id="update">Update Content</button>

    <script>
        document.getElementById('update').addEventListener('click', () => {
            const content = document.getElementById('content');
            content.style.display = 'none'; // Hide element to batch changes
            content.innerHTML = 'Updated Content';
            content.style.display = 'block'; // Show element after updates
        });
    </script>
</body>
</html>

Cet exemple montre comment regrouper les modifications apportées à un élément DOM pour minimiser les reflows et les repaints. En masquant l'élément avant d'effectuer plusieurs mises à jour, puis en l'affichant ensuite, vous évitez les reflows et les repaints intermédiaires.

Utiliser des classes CSS pour les modifications

Appliquez les modifications CSS via des classes plutôt qu'en manipulant directement les styles :

<!DOCTYPE html>
<html>
<head>
    <title>Use CSS Classes</title>
    <style>
        .hidden { display: none; }
        .highlight { color: red; font-weight: bold; }
    </style>
</head>
<body>
    <div id="content">Hello World</div>
    <button id="toggle">Toggle Highlight</button>

    <script>
        document.getElementById('toggle').addEventListener('click', () => {
            const content = document.getElementById('content');
            content.classList.toggle('highlight');
        });
    </script>
</body>
</html>

Cet exemple montre comment utiliser des classes CSS pour appliquer plusieurs changements de style en une seule fois, ce qui est plus efficace que de modifier des propriétés de style individuellement. Basculer une classe qui change plusieurs styles permet de réduire le nombre de reflows et de repaints.

Utiliser les fragments de document pour les performances

Qu'est-ce qu'un fragment de document ?

Un fragment de document est un conteneur léger utilisé pour regrouper un ensemble de nœuds. Il ne fait pas partie de l'arbre DOM principal, ce qui signifie que les modifications qui lui sont apportées ne déclenchent pas de reflows ni de repaints.

Info

Lorsque vous effectuez plusieurs manipulations du DOM, utilisez DocumentFragment pour regrouper vos modifications et les ajouter au DOM en une seule opération. Cette approche minimise les reflows et les repaints, améliorant considérablement les performances.

Exemple d'utilisation des fragments de document

<!DOCTYPE html>
<html>
<head>
    <title>Document Fragments</title>
</head>
<body>
    <div id="list"></div>
    <button id="populate">Populate List</button>

    <script>
        document.getElementById('populate').addEventListener('click', (event) => {
            const fragment = document.createDocumentFragment();
            for (let i = 1; i <= 25; i++) {
                const item = document.createElement('div');
                item.textContent = `Item ${i}`;
                fragment.appendChild(item);
            }
            document.getElementById('list').appendChild(fragment);
            event.target.disabled = true; // Disable the button
        });
    </script>
</body>
</html>

Cet exemple crée 25 éléments div et les ajoute à un fragment de document. Ce n'est qu'après que tous les éléments ont été ajoutés au fragment que celui-ci est rattaché au DOM en une seule opération. Cette approche minimise les reflows et les repaints en ne mettant à jour le DOM qu'une seule fois.

Cloner des nœuds

La méthode cloneNode()

La méthode cloneNode() est utilisée pour créer une copie d'un nœud. Elle peut cloner le nœud seul ou le nœud avec tous ses enfants.

Cloner un nœud sans ses enfants

<!DOCTYPE html>
<html>
<head>
    <title>Cloning Nodes</title>
</head>
<body>
    <div id="original">Original Node</div>
    <button id="clone">Clone Node</button>

    <script>
        document.getElementById('clone').addEventListener('click', () => {
            const original = document.getElementById('original');
            const clone = original.cloneNode(false); // Clone without children
            clone.id = 'clone';
            clone.textContent = 'Cloned Node';
            document.body.appendChild(clone);
        });
    </script>
</body>
</html>

Cet exemple montre comment cloner un nœud sans ses enfants à l'aide de la méthode cloneNode(false). Le nœud cloné copiera les attributs et le contenu textuel du nœud original, mais pas ses nœuds enfants.

Cloner un nœud avec ses enfants

<!DOCTYPE html>
<html>
<head>
    <title>Cloning Nodes with Children</title>
</head>
<body>
    <div id="original">
        Original Node
        <span>Child Node</span>
    </div>
    <button id="clone">Clone Node with Children</button>

    <script>
        document.getElementById('clone').addEventListener('click', () => {
            const original = document.getElementById('original');
            const clone = original.cloneNode(true); // Clone with children
            clone.id = 'clone';
            document.body.appendChild(clone);
        });
    </script>
</body>
</html>

Cet exemple montre comment cloner un nœud ainsi que tous ses enfants à l'aide de la méthode cloneNode(true). Le nœud cloné inclura le contenu du nœud original et tous ses nœuds descendants.

Conclusion

Une manipulation efficace du DOM est essentielle pour créer des applications web performantes. Commencez par maîtriser les méthodes fondamentales pour créer, insérer, remplacer et supprimer des éléments, puis ajoutez les optimisations : regroupez vos mises à jour, préférez les classes CSS aux styles inline, utilisez DocumentFragment pour les insertions en masse, et clonez les nœuds lorsque vous avez besoin de structures répétées. Ensemble, ces techniques maintiennent la réactivité de vos pages même lorsque le DOM grossit.

Sujets connexes

Pratique

Pratique
Lesquelles des méthodes suivantes sont utilisées pour manipuler le DOM en JavaScript ?
Lesquelles des méthodes suivantes sont utilisées pour manipuler le DOM en JavaScript ?
Was this page helpful?