Document.importNode VS Node.cloneNode (real example) Document.importNode VS Node.cloneNode (real example) javascript javascript

Document.importNode VS Node.cloneNode (real example)


Alohci is right: there's not much of a difference, since web compatibility forced the browsers to implicitly adoptNode() before inserting a node into another document.

Before you insert the cloned node into a new document, there's a difference: the owner document of the node returned by the cloneNode(original) is the same as of the original node, and the new document if you call newDocument.importNode(original). You can see this difference if you use ownerDocument or related properties (such as baseURI).

But if you call importNode on the same document that the original node belongs to, there's no difference whatsoever.


Simply put:

element.cloneNode() is used to clone a node from current document, for instance, with shadow DOM when you append any DOM element such as a template. There you call shadowDOM.appendChild(template.content.cloneNode(true)), where template is an instance of <template> defined in your HTML. Here you are telling JS to grab the element from the current DOM and append it to the shadow DOM.

document.importNode() is used to clone a node from another document, for instance, with <iframe> which has its own DOM, to show any element from an iframe into your DOM.

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

document.adoptNode() is another method which is quite similar to importNode() with a difference that it removes the original element from its parent DOM. importNode() copies the original element without removing while adoptNode() completely removes the original element from its DOM.

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


I started learning JavaScript a few months ago in my classes and came upon one distinction between those two methods today. Since Iaroslav Baranov wanted an example, here it is:

I was trying to clone an HTML template tag with its content to create a gallery of books (like a product listing page for an e-commerce website). Here is the 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>

Here is the JS function I tried to run at first:

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);}

This was working flawlessly, but the browser kept searching for an unknown weird image to replace for the coverImage variable:

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

The solution

To avoid this error, all I had to do was to switch the first line of the for loop - the one using importNode() - by this:

templateClonde = template.content.cloneNode(true);

The explanation

I have no idea why cloneNode() does not throw an error while importNode() does. My only guess is that importNode() should not be used if the clone reference and the appended clone are in the same DOM.

Anyway, I would be glad if someone could further explain the distinction between the two methods, but since OP asked for an example, here was mine.