Start · Sprachen · JavaScript · Referenz · Document.adoptNode()

Document.adoptNode()

Methode

Überträgt einen Knoten samt Unterbaum aus einem anderen Dokument in das aktuelle Dokument und entfernt ihn dabei aus seinem bisherigen Elternknoten.

seit JavaScript DOM Level 3 – Baseline: alle modernen Browser Kategorie: webapi

Signatur

Document.prototype.adoptNode(externalNode)

Beschreibung

document.adoptNode() übernimmt einen Knoten aus einem fremden Dokument, z. B. aus einem <iframe>, einem per DOMParser erzeugten Dokument oder dem content eines <template>. Dabei wird ownerDocument des Knotens und aller Nachfahren auf das aufrufende Dokument gesetzt. Hat der Knoten ein Elternelement, wird er dort entfernt.

Im Unterschied zu document.importNode() wird keine Kopie erzeugt. Es wird genau dieser Knoten verschoben. Das Original gibt es im Quelldokument danach nicht mehr. Wenn die Quelle unverändert bleiben soll, ist importNode() die richtige Wahl.

Nach der Übernahme ist der Knoten noch nicht im Dokumentbaum eingehängt. Dafür braucht es z. B. appendChild(), append() oder insertBefore(). Moderne Browser übernehmen Knoten bei solchen Einfügemethoden ohnehin automatisch. Ein expliziter adoptNode()-Aufruf macht den Code trotzdem klarer und ist nötig, wenn man den Knoten vor dem Einfügen bearbeiten will (z. B. Bilder mit relativen URLs, die im neuen Dokument aufgelöst werden sollen).

Parameter

Name Typ Default Beschreibung
$externalNode Pflicht Node Der Knoten, der übernommen werden soll, samt Unterbaum. Ist er in einem Baum eingehängt, wird er dort vorher entfernt. Document-Knoten sind nicht erlaubt.

Rückgabewert

Typ
Node
Beschreibung
Derselbe Knoten, den man übergeben hat (keine Kopie). Sein ownerDocument ist jetzt das aufrufende Dokument und parentNode ist null.

Beispiele

Element aus einem gleich-originigen iframe übernehmen

const frame = document.querySelector('#vorschau');
const frameDoc = frame.contentDocument;

const artikel = frameDoc.querySelector('article');
const uebernommen = document.adoptNode(artikel);

console.log(uebernommen === artikel);               // derselbe Knoten
console.log(uebernommen.ownerDocument === document);
console.log(frameDoc.querySelector('article'));      // aus dem iframe entfernt

document.querySelector('main').append(uebernommen);
true true null

HTML-Fragment mit DOMParser parsen und übernehmen

const html = `<ul class="liste"><li>Äpfel</li><li>Birnen</li></ul>`;
const fremdDoc = new DOMParser().parseFromString(html, 'text/html');

const liste = document.adoptNode(fremdDoc.body.firstElementChild);
console.log(liste.parentNode);          // noch nicht eingehängt

liste.classList.add('importiert');
document.body.append(liste);
console.log(liste.ownerDocument === document);
null true

Unterschied zu importNode()

const quelle = new DOMParser().parseFromString('<p id="x">Hallo</p>', 'text/html');

const kopie = document.importNode(quelle.getElementById('x'), true);
console.log(quelle.getElementById('x') !== null); // Original bleibt

const verschoben = document.adoptNode(quelle.getElementById('x'));
console.log(quelle.getElementById('x'));           // Original ist weg
console.log(kopie !== verschoben);
true null true

// Wichtig · Fallstricke

  • Kein Klonen: Der Knoten verschwindet aus dem Quelldokument. Für eine Kopie importNode(node, true) oder cloneNode(true) verwenden.
  • Fehler: Ist der Knoten ein Document, wirft die Methode eine NotSupportedError-DOMException. Ist er ein ShadowRoot, wirft sie eine HierarchyRequestError.
  • Same-Origin-Policy: Auf contentDocument eines iframes von einer anderen Origin kann man nicht zugreifen (Rückgabe null). Knoten lassen sich dann also auch nicht übernehmen.
  • Sicherheit: Knoten aus nicht vertrauenswürdigem HTML (z. B. per DOMParser) können Event-Handler-Attribute wie onerror enthalten. Sobald man sie ins aktive Dokument einhängt, können diese ausgeführt werden (XSS). Deshalb vorher bereinigen, z. B. mit DOMPurify oder der Sanitizer-API.
  • Templates: Wenn template.content übernommen wird, ist die Vorlage danach leer. Für wiederverwendbare Vorlagen deshalb importNode() nehmen.
  • Custom Elements: Beim Übernehmen wird der Lifecycle-Callback adoptedCallback() aufgerufen.
  • Die Methode wird von allen aktuellen Browsern unterstützt.