Signatur
Beschreibung
document.importNode() erzeugt eine Kopie eines Knotens, der zu einem anderen Dokument gehört, etwa zu einem <template>-Inhalt, einem <iframe> oder einem mit DOMParser erzeugten Dokument. Die Kopie gehört danach zum aufrufenden Dokument (ownerDocument zeigt auf dieses). Sie hat aber noch keinen Elternknoten und ist daher noch nicht im DOM-Baum sichtbar. Einfügen musst du sie selbst, z. B. mit appendChild() oder append().
Der Originalknoten bleibt im Quelldokument unverändert. Das ist der wichtigste Unterschied zu document.adoptNode(): Diese Methode verschiebt den Knoten und entfernt ihn dabei aus dem Quelldokument.
Typische Einsatzfälle sind das mehrfache Klonen von Vorlagen (template.content), das Übernehmen von Inhalten aus einem per fetch() geladenen und geparsten HTML-Dokument oder das Kopieren von Elementen zwischen Fenstern bzw. Frames. Mit dem Parameter deep legst du fest, ob nur der Knoten selbst oder auch sein gesamter Unterbaum kopiert wird.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $externalNode Pflicht | Node | DocumentFragment | Der Knoten aus einem anderen Dokument, der kopiert werden soll. Ein Document oder ShadowRoot kann nicht importiert werden. |
|
| $deep | boolean | false | Bei true wird der komplette Unterbaum mitkopiert, also alle Kindknoten und Textinhalte. Bei false wird nur der Knoten selbst mit seinen Attributen kopiert. |
Rückgabewert
externalNode. Sie gehört zum aufrufenden Dokument, hat aber noch keinen Elternknoten (parentNode === null).Beispiele
Template-Inhalt mehrfach klonen
// HTML: <template id="row"><li class="item"><span></span></li></template><ul id="list"></ul>
const template = document.getElementById('row');
const list = document.getElementById('list');
const fruits = ['Apfel', 'Birne', 'Kirsche'];
for (const fruit of fruits) {
// template.content gehört zu einem eigenen Dokument, daher wird importiert
const clone = document.importNode(template.content, true);
clone.querySelector('span').textContent = fruit;
list.appendChild(clone);
}
console.log(list.children.length);
Inhalt aus einem geparsten HTML-Dokument übernehmen
const loadSnippet = async (url) => {
const html = await (await fetch(url)).text();
const parsed = new DOMParser().parseFromString(html, 'text/html');
const article = parsed.querySelector('article');
const imported = document.importNode(article, true);
console.log(imported.ownerDocument === document); // true
document.querySelector('main').append(imported);
};
loadSnippet('/snippets/news.html');
Flache und tiefe Kopie im Vergleich
const doc = new DOMParser().parseFromString(
'<div id="box" class="card"><p>Hallo</p></div>',
'text/html'
);
const source = doc.getElementById('box');
const shallow = document.importNode(source, false);
const deep = document.importNode(source, true);
console.log(shallow.outerHTML);
console.log(deep.outerHTML);
console.log(source.ownerDocument === doc); // Original bleibt im Quelldokument
Element aus einem gleichherkünftigen iframe kopieren
const frame = document.querySelector('iframe');
frame.addEventListener('load', () => {
const header = frame.contentDocument.querySelector('header');
const copy = document.importNode(header, true);
document.body.prepend(copy);
});
// Wichtig · Fallstricke
- Nicht eingefügt: Der zurückgegebene Knoten hängt noch nicht im DOM. Ohne
appendChild(),append()o. Ä. ist er nicht sichtbar. - Standardwert von
deep: Heute ist dasfalse. Ältere Browser verlangten den Parameter zwingend. Gib ihn daher immer ausdrücklich an und setze ihn bei Vorlagen fast immer auftrue. - Keine Ereignis-Listener: Mit
addEventListener()registrierte Listener werden nicht mitkopiert. Inline-Attribute wieonclickdagegen schon, weil sie Attribute sind. - Doppelte IDs: Kopien behalten ihre
id-Attribute. Bei mehrfachem Import können so doppelte IDs entstehen. - Nicht importierbar:
Document- undShadowRoot-Knoten lösen eineNotSupportedError-DOMExceptionaus. - Skripte:
<script>-Elemente aus einem mitDOMParsererzeugten Dokument gelten als bereits verarbeitet und werden nach dem Import in der Regel nicht ausgeführt. - Sicherheit: Übernimmst du HTML aus fremden Quellen, können gefährliche Attribute wie
onerroroderjavascript:-URLs mitkommen und nach dem Einfügen aktiv werden (XSS). Bereinige nicht vertrauenswürdige Inhalte vorher, etwa mit DOMPurify. Beiiframes gilt die Same-Origin-Policy: Auf dascontentDocumentfremder Herkunft kannst du nicht zugreifen. - Alternative: Bei
template.contentfunktioniert meist auchtemplate.content.cloneNode(true). Beim Einfügen wird der Knoten dann automatisch übernommen.importNode()gibt den richtigen Besitzer aber sofort vor, was z. B. für Custom Elements, die direkt aktualisiert werden, relevant ist. - Die Methode wird von allen Browsern unterstützt, einschließlich sehr alter Versionen.