W3docs

JavaScript DOM-Manipulationstechniken

JavaScript DOM-Manipulation: Elemente erstellen, einfügen, ersetzen und entfernen sowie Optimierungen mit Batching, Document Fragments und Node-Klonen für weniger Reflows.

DOM (Document Object Model) Manipulation ist ein zentraler Aspekt der Webentwicklung, mit dem Sie dynamische, interaktive Seiten erstellen können, indem Sie die Struktur, den Inhalt und das Styling des Dokuments über JavaScript verändern. Dieser Leitfaden beginnt mit den grundlegenden Techniken zum Erstellen, Einfügen, Ersetzen und Entfernen von Elementen und behandelt anschließend Best Practices und Performance-Optimierungen — Batching, Document Fragments und Node-Klonen —, die diese Änderungen schnell halten.

Wenn Sie noch kein Element ausgewählt haben, beginnen Sie mit dem Auswählen von DOM-Elementen. Um den Baum, den Sie bearbeiten, besser zu verstehen, lesen Sie die DOM-Nodes verstehen.

Grundlegende Manipulationstechniken

Jede Änderung am DOM fällt in eine von vier Kategorien: Nodes erstellen, einfügen, ersetzen oder entfernen.

Elemente erstellen

Verwenden Sie document.createElement(), um ein Element im Speicher aufzubauen, und legen Sie dann Inhalt und Attribute fest, bevor Sie es in die Seite einfügen. Ein erstellter Node ist erst sichtbar, wenn er an das Dokument angehängt wird.

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>

Bevorzugen Sie textContent gegenüber innerHTML, wenn Sie einfachen Text einfügen — es ist schneller und vermeidet das Sicherheitsrisiko durch das Injizieren von nicht escaptem HTML.

Elemente einfügen

Sobald ein Element vorhanden ist, hängen Sie es mit einer dieser Methoden an:

  • parent.append(node) — fügt den Node als letztes Kind hinzu (akzeptiert auch einfache Strings).
  • parent.prepend(node) — fügt ihn als erstes Kind hinzu.
  • target.before(node) / target.after(node) — fügt ein Geschwisterelement vor oder nach target ein.
  • parent.appendChild(node) — die klassische API; hängt einen einzelnen Node an und gibt ihn zurück.
  • parent.insertBefore(node, reference) — fügt node vor dem reference-Kind ein.
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

Verwenden Sie insertAdjacentHTML(), um einen HTML-String an einer genauen Position einzufügen, ohne das gesamte übergeordnete Element neu zu parsen:

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

Elemente ersetzen und entfernen

  • oldNode.replaceWith(newNode) — ersetzt oldNode durch newNode an derselben Stelle.
  • element.remove() — entfernt das Element aus dem DOM.
  • parent.replaceChild(newNode, oldNode) und parent.removeChild(child) — die älteren Entsprechungen.
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

Die modernen Methoden (append, prepend, before, after, replaceWith, remove) sind leichter lesbar als die veralteten appendChild/insertBefore/replaceChild/removeChild und akzeptieren gleichzeitig mehrere Nodes und Strings. Greifen Sie zuerst auf diese zurück; verwenden Sie die veraltete API nur, wenn Sie sehr alte Browser unterstützen müssen.

Best Practices für die DOM-Manipulation

Direkten DOM-Zugriff minimieren

Der Zugriff auf den DOM kann langsam sein, da er den Browser dazu veranlassen kann, das Layout neu zu berechnen und Elemente neu zu zeichnen. Um den direkten DOM-Zugriff zu minimieren:

  • Fassen Sie DOM-Aktualisierungen zusammen, anstatt viele kleine Aktualisierungen einzeln durchzuführen.
  • Verwenden Sie Variablen, um Referenzen auf häufig verwendete Elemente zu speichern.

Event-Handling optimieren

Hängen Sie Event-Handler effizient an:

  • Verwenden Sie Event-Delegation, um die Anzahl der Event-Listener zu reduzieren.
  • Vermeiden Sie es, zu viele Event-Listener direkt an Elemente anzuhängen.

Nicht benötigte Elemente entfernen

Entfernen Sie Elemente, die nicht mehr benötigt werden, um Speicher freizugeben und die Performance zu verbessern:

  • Verwenden Sie die Methoden removeChild oder remove, um Elemente aus dem DOM zu löschen.

Reflows und Repaints minimieren

Was sind Reflows und Repaints?

  • Reflows treten auf, wenn sich das Layout eines Teils der Seite ändert, wodurch der Browser die Positionen und Größen der Elemente neu berechnen muss.
  • Repaints entstehen, wenn sich das visuelle Erscheinungsbild von Elementen ändert, ohne das Layout zu beeinflussen (z.B. Farbänderungen).

Techniken zur Minimierung von Reflows und Repaints

Änderungen bündeln

Fassen Sie mehrere Änderungen zusammen, um wiederholte Reflows und Repaints zu vermeiden:

<!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>

Dieses Beispiel zeigt, wie Änderungen an einem DOM-Element gebündelt werden, um Reflows und Repaints zu minimieren. Indem das Element vor mehreren Aktualisierungen ausgeblendet und danach wieder eingeblendet wird, lassen sich zwischenzeitliche Reflows und Repaints vermeiden.

CSS-Klassen für Änderungen verwenden

Wenden Sie CSS-Änderungen mithilfe von Klassen an, anstatt Stile direkt zu manipulieren:

<!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>

Dieses Beispiel zeigt, wie CSS-Klassen verwendet werden, um mehrere Stiländerungen auf einmal anzuwenden, was effizienter ist als das Ändern einzelner Style-Eigenschaften. Das Umschalten einer Klasse, die mehrere Stile ändert, hilft, die Anzahl der Reflows und Repaints zu reduzieren.

Document Fragments für bessere Performance

Was ist ein Document Fragment?

Ein Document Fragment ist ein leichtgewichtiger Container, der eine Gruppe von Nodes aufnehmen kann. Er ist nicht Teil des eigentlichen DOM-Baums, was bedeutet, dass Änderungen daran keine Reflows und Repaints auslösen.

Info

Verwenden Sie bei mehreren DOM-Manipulationen DocumentFragment, um Ihre Änderungen zu bündeln und in einem einzigen Vorgang an den DOM anzuhängen. Dieser Ansatz minimiert Reflows und Repaints und verbessert die Performance erheblich.

Beispiel für die Verwendung von Document Fragments

<!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>

Dieses Beispiel erstellt 25 div-Elemente und hängt sie an ein Document Fragment an. Erst nachdem alle Elemente zum Fragment hinzugefügt wurden, wird das Fragment in einem einzigen Schritt an den DOM angehängt. Dieser Ansatz minimiert Reflows und Repaints, indem der DOM nur einmal aktualisiert wird.

Nodes klonen

Die Methode cloneNode()

Die Methode cloneNode() wird verwendet, um eine Kopie eines Nodes zu erstellen. Sie kann den Node selbst oder den Node zusammen mit seinen Kindern klonen.

Einen Node ohne Kinder klonen

<!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>

Dieses Beispiel zeigt, wie ein Node ohne seine Kinder mithilfe der Methode cloneNode(false) geklont wird. Der geklonte Node übernimmt die Attribute und den Textinhalt des ursprünglichen Nodes, jedoch nicht seine Kind-Nodes.

Einen Node mit Kindern klonen

<!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>

Dieses Beispiel zeigt, wie ein Node zusammen mit seinen Kindern mithilfe der Methode cloneNode(true) geklont wird. Der geklonte Node enthält den Inhalt des ursprünglichen Nodes sowie alle seine Nachfahren-Nodes.

Fazit

Effiziente DOM-Manipulation ist entscheidend für leistungsstarke Webanwendungen. Beginnen Sie damit, die grundlegenden Methoden zum Erstellen, Einfügen, Ersetzen und Entfernen von Elementen zu beherrschen, und wenden Sie dann die Optimierungen an: Fassen Sie Ihre Aktualisierungen zusammen, bevorzugen Sie CSS-Klassen gegenüber Inline-Stilen, verwenden Sie DocumentFragment für Masseneinfügungen und klonen Sie Nodes, wenn Sie wiederkehrende Strukturen benötigen. Zusammen halten diese Techniken Ihre Seiten reaktionsfähig, selbst wenn der DOM wächst.

Verwandte Themen

Übungen

Übung
Welche der folgenden Methoden werden zur Manipulation des DOM in JavaScript verwendet?
Welche der folgenden Methoden werden zur Manipulation des DOM in JavaScript verwendet?
Was this page helpful?