Signatur
Beschreibung
replaceWith() entfernt das aufrufende Element aus dem DOM und setzt an seine Stelle die übergebenen Knoten bzw. Strings, und zwar in der Reihenfolge der Argumente. Strings werden nicht als HTML interpretiert, sondern als Text-Knoten eingefügt. Deshalb ist die Methode sicher gegenüber XSS, wenn Nutzereingaben als Strings übergeben werden.
Die Methode ist der moderne und kürzere Ersatz für das ältere Muster parent.replaceChild(neu, alt): Man braucht keine Referenz auf den Elternknoten, und man kann mehrere Knoten auf einmal einsetzen. Typische Einsatzfälle sind das Austauschen eines Platzhalters oder Ladeindikators gegen fertigen Inhalt, das Umwandeln eines Elementtyps (z. B. <span> zu <input> beim Inline-Bearbeiten) und das „Auspacken“ eines Elements, sodass nur seine Kinder übrig bleiben.
Übergebene Knoten, die bereits an anderer Stelle im DOM hängen, werden verschoben und nicht kopiert. Hat das Element keinen Elternknoten, passiert nichts. Ruft man die Methode ohne Argumente auf, wird das Element einfach entfernt, genau wie bei remove().
Die Methode stammt aus dem Mixin ChildNode und steht deshalb auch an CharacterData (z. B. Text, Comment) und DocumentType zur Verfügung.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $...nodes | Node | string | Beliebig viele Node-Objekte oder Strings, die an die Stelle des Elements treten. Strings werden zu Text-Knoten. Auch ein DocumentFragment ist erlaubt; eingefügt werden dann seine Kinder. Andere Werte (z. B. Zahlen) werden in Strings umgewandelt. |
Rückgabewert
undefined).Beispiele
Ladeindikator durch geladenen Inhalt ersetzen
// HTML: <div id="spinner">Lade…</div>
const spinner = document.querySelector('#spinner');
const loadUser = async () => {
const res = await fetch('https://jsonplaceholder.typicode.com/users/1');
const user = await res.json();
const card = document.createElement('article');
card.className = 'user-card';
const heading = document.createElement('h2');
heading.textContent = user.name;
card.append(heading, `E-Mail: ${user.email}`);
spinner.replaceWith(card);
};
loadUser();
Mehrere Knoten und Strings gemischt einsetzen
// HTML: <p>Hallo <span id="name">???</span>!</p>
const placeholder = document.querySelector('#name');
const strong = document.createElement('strong');
strong.textContent = 'Anna';
placeholder.replaceWith('liebe ', strong, ' (Admin)');
console.log(document.querySelector('p').innerHTML);
Inline-Bearbeitung: span gegen input tauschen und zurück
// HTML: <span class="editable">Titel</span>
const label = document.querySelector('.editable');
label.addEventListener('dblclick', () => {
const input = document.createElement('input');
input.value = label.textContent;
label.replaceWith(input);
input.focus();
input.addEventListener('blur', () => {
label.textContent = input.value; // Text bleibt sicher, kein HTML
input.replaceWith(label); // ursprüngliches Element wieder einsetzen
}, { once: true });
});
Element auspacken (nur die Kinder behalten)
// HTML: <div class="wrapper"><p>A</p><p>B</p></div>
const wrapper = document.querySelector('.wrapper');
wrapper.replaceWith(...wrapper.childNodes);
console.log(document.querySelectorAll('p').length, document.querySelector('.wrapper'));
// Wichtig · Fallstricke
- Strings sind kein HTML:
el.replaceWith('<b>x</b>')fügt den Text wörtlich ein. Für HTML-Markup verwendet manel.outerHTML = …oder ein<template>. Bei Nutzereingaben ist das Verhalten vonreplaceWith()aber gerade der Vorteil, weil keine XSS-Gefahr entsteht. - Knoten werden verschoben: Ein Knoten, der schon im DOM hängt, wird von seiner alten Position entfernt. Wer ihn an beiden Stellen braucht, übergibt eine Kopie mit
node.cloneNode(true). - Event-Listener: Listener am ersetzten Element gelten nicht für die neuen Knoten. Das alte Element behält seine Listener, falls es wieder eingefügt wird.
- Ohne Elternknoten passiert nichts, und es wird kein Fehler geworfen. Eine
HierarchyRequestError-DOMExceptiontritt auf, wenn die Einfügung ungültig ist, z. B. wenn man ein Element durch einen seiner eigenen Vorfahren ersetzen will. - Live-Collections:
el.replaceWith(...el.childNodes)funktioniert, weil die Argumente vor dem Einfügen ausgewertet werden. In eigenen Schleifen überchildNodessollte man dagegen vorher mitArray.from()kopieren. - Kompatibilität: Wird von allen modernen Browsern unterstützt, nicht aber vom Internet Explorer. Dort bleibt nur
parentNode.replaceChild().