Signatur
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
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);
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);
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);
// Wichtig · Fallstricke
- Kein Klonen: Der Knoten verschwindet aus dem Quelldokument. Für eine Kopie
importNode(node, true)odercloneNode(true)verwenden. - Fehler: Ist der Knoten ein
Document, wirft die Methode eineNotSupportedError-DOMException. Ist er einShadowRoot, wirft sie eineHierarchyRequestError. - Same-Origin-Policy: Auf
contentDocumenteines iframes von einer anderen Origin kann man nicht zugreifen (Rückgabenull). Knoten lassen sich dann also auch nicht übernehmen. - Sicherheit: Knoten aus nicht vertrauenswürdigem HTML (z. B. per
DOMParser) können Event-Handler-Attribute wieonerrorenthalten. 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 deshalbimportNode()nehmen. - Custom Elements: Beim Übernehmen wird der Lifecycle-Callback
adoptedCallback()aufgerufen. - Die Methode wird von allen aktuellen Browsern unterstützt.