Document.importNode VS Node.cloneNode (echtes Beispiel)

Lesezeit: 4 Minuten

Document.importNode in der Spezifikation

Node.cloneNode in der Spezifikation

Diese beiden Methoden funktionieren gleichermaßen. Bitte geben Sie mir ein echtes Beispiel, an dem ich den Unterschied zwischen diesen Methoden erkennen kann.

  • Es ist möglich, dass Sie in modernen Browsern keinen Unterschied erkennen können (außer dass sie offensichtlich auf verschiedenen Schnittstellen definiert sind). Historisch gesehen diente importNode in DOM zum Kopieren eines Knotens aus einem anderen Dokument, während cloneNode für eine Kopie eines Knotens im selben Dokument war, aber DOM4 hebt die Unterscheidung auf, da die Unterscheidung keine nützlichen Auswirkungen hat.

    – Alohci

    8. September 2016 um 0:07 Uhr


Alohci hat Recht: Da gibt es keinen großen Unterschied Webkompatibilität zwang die Browser implizit dazu adoptNode() bevor Sie einen Knoten in ein anderes Dokument einfügen.

Vor Sie fügen den geklonten Knoten in ein neues Dokument ein, es gibt einen Unterschied: das Besitzerdokument des Knotens wird von der zurückgegeben cloneNode(original) ist das gleiche wie der ursprüngliche Knoten und das neue Dokument, wenn Sie es aufrufen newDocument.importNode(original). Sie können diesen Unterschied sehen, wenn Sie verwenden ownerDocument oder verwandte Eigenschaften (z. B. baseURI).

Aber wenn Sie importNode für dasselbe Dokument aufrufen, zu dem der ursprüngliche Knoten gehört, gibt es überhaupt keinen Unterschied.

Einfach gesagt:

element.cloneNode() wird verwendet, um einen Knoten aus dem aktuellen zu klonen documentzum Beispiel mit Schatten-DOM, wenn Sie ein beliebiges DOM-Element wie a anhängen template. Dort rufst du an shadowDOM.appendChild(template.content.cloneNode(true))wo template ist eine Instanz von <template> in Ihrem HTML definiert. Hier weisen Sie JS an, das Element aus dem aktuellen DOM zu holen und an das Schatten-DOM anzuhängen.

document.importNode() wird verwendet, um beispielsweise einen Knoten aus einem anderen Dokument zu klonen <iframe> das ein eigenes DOM hat, um jedes Element aus einer anzuzeigen iframe in Ihr DOM.

var frame = document.getElementsByTagName("IFRAME")[0]
var h = frame.contentWindow.document.getElementsByTagName("H1")[0];
var x = document.importNode(h);

document.adoptNode() ist eine andere Methode, die ziemlich ähnlich ist importNode() mit dem Unterschied, dass es das ursprüngliche Element aus seinem übergeordneten DOM entfernt. importNode() kopiert das ursprüngliche Element, ohne while zu entfernen adoptNode() entfernt das ursprüngliche Element vollständig aus seinem DOM.

var frame = document.getElementsByTagName("IFRAME")[0]
var h = frame.contentWindow.document.getElementsByTagName("H1")[0];
var x = document.adoptNode(h);

  • Ich sehe viele Codebeispiele online, die importNode mit Vorlageninhalt anstelle von cloneNode verwenden …

    – Chris_F

    16. Dezember 2018 um 6:54 Uhr

Benutzer-Avatar
deProulx

Ich habe vor ein paar Monaten angefangen, JavaScript in meinen Kursen zu lernen, und bin heute auf einen Unterschied zwischen diesen beiden Methoden gestoßen. Da Iaroslav Baranov ein Beispiel haben wollte, hier ist es:

Ich habe versucht, ein HTML-Vorlagen-Tag mit seinem Inhalt zu klonen, um eine Büchergalerie zu erstellen (wie eine Produktlistenseite für eine E-Commerce-Website). Hier ist der HTML-Code:

<template id="modeleLivre">
<article class="livre">
  <header class="titre">${titre}</header>
  <p class="imageCouverture">
    <img src="images/${imageCouverture}">
  </p>
  <p class="auteur">${auteur}</p>
  <p class="prix">${prix} €</p>
  <p class="genre">${genre}</p>
  <input type="button" class="btn_achat" value="Ajouter au panier">
</article>

Hier ist die JS-Funktion, die ich zuerst versucht habe auszuführen:

let template = document.getElementById("modeleLivre");

let templateClone;

for (let i = 0; i < gallery.length; i++) {
    templateClone = document.importNode(template.content, true);
    let eBook = templateClone.querySelector(".livre");
    let title = catalogue[i].getTitle();
    let coverImage = catalogue[i].getCoverImage();
    let author = catalogue[i].getAuthor();
    let price = catalogue[i].getPrice();
    let book = eBook.innerHTML;
    
    eBook.innerHTML = book.replace('${titre}', title).replace('${imageCouverture}', coverImage).replace('${auteur}', author).replace('${prix}', price);

    bookListing.appendChild(templateClone);
}

Dies funktionierte einwandfrei, aber der Browser suchte weiter nach einem unbekannten seltsamen Bild, um die coverImage-Variable zu ersetzen:

GET ../images/$%7BimageCouverture%7D | net::ERR_FILE_NOT_FOUND

Die Lösung

Um diesen Fehler zu vermeiden, musste ich lediglich die erste Zeile der ändern für Schleife – derjenige, der importNode() verwendet – dadurch:

templateClone = template.content.cloneNode(true);

Die Erklärung

Ich habe keine Ahnung, warum cloneNode() keinen Fehler auslöst, während importNode() dies tut. Meine einzige Vermutung ist, dass importNode() nicht verwendet werden sollte, wenn sich die Klonreferenz und der angehängte Klon im selben DOM befinden.

Wie auch immer, ich würde mich freuen, wenn jemand den Unterschied zwischen den beiden Methoden näher erläutern könnte, aber da OP nach einem Beispiel gefragt hat, hier war meins.

1246390cookie-checkDocument.importNode VS Node.cloneNode (echtes Beispiel)

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy