Document.importNode VS Node.cloneNode(实例)

Iar*_*nov 31 html javascript w3c dom

规范中的Document.importNode

规范中的Node.cloneNode

这两种方法同样有效.请给我一个真实的例子,我可以看到这些方法之间的区别.

Nic*_*lay 22

Alohci是对的:没有太大区别,因为在将节点插入另一个文档之前,Web兼容性会强制浏览器隐式adoptNode().

将克隆节点插入新文档之前,存在一个区别:由返回的节点的所有者文档cloneNode(original)与原始节点相同,如果调用则返回新文档newDocument.importNode(original).如果使用ownerDocument或相关属性(例如baseURI),您可以看到这种差异.

但是如果在原始节点所属的同一文档上调用importNode,则没有任何区别.


pat*_*729 10

简单的说:

element.cloneNode()用于从 current 克隆节点document,例如,当您附加任何 DOM 元素(例如template. 在那里您调用shadowDOM.appendChild(template.content.cloneNode(true)),其中template<template>在您的 HTML中定义的实例。在这里,您告诉 JS 从当前 DOM 中获取元素并将其附加到 shadow DOM。

document.importNode()用于从另一个文档中克隆一个节点,例如,<iframe>它有自己的 DOM,以将任何元素显示iframe到您的 DOM 中。

var frame = document.getElementsByTagName("IFRAME")[0]
var h = frame.contentWindow.document.getElementsByTagName("H1")[0];
var x = document.importNode(h);
Run Code Online (Sandbox Code Playgroud)

document.adoptNode()是另一种非常相似的方法,importNode()不同之处在于它从其父 DOM 中删除原始元素。importNode()复制原始元素而不删除,而adoptNode()从其 DOM 中完全删除原始元素。

var frame = document.getElementsByTagName("IFRAME")[0]
var h = frame.contentWindow.document.getElementsByTagName("H1")[0];
var x = document.adoptNode(h);
Run Code Online (Sandbox Code Playgroud)

  • 我在网上看到很多代码示例使用带有模板内容的 importNode 而不是 cloneNode ... (2认同)

deP*_*ulx 5

几个月前我开始在课堂上学习 JavaScript,今天发现了这两种方法之间的一个区别。由于Iaroslav Baranov想要一个例子,这里是:

我试图用它的内容克隆一个 HTML 模板标签来创建一个书库(比如一个电子商务网站的产品列表页面)。这是 HTML 代码:

<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>
Run Code Online (Sandbox Code Playgroud)

这是我最初尝试运行的 JS 函数:

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);
}
Run Code Online (Sandbox Code Playgroud)

这是完美的工作,但浏览器一直在寻找一个未知的奇怪图像来替换coverImage变量:

获取 ../images/$%7BimageCouvture%7D | net::ERR_FILE_NOT_FOUND

解决方案

为了避免这个错误,我所要做的就是切换for 循环的第一行- 使用 importNode() 的那一行 - 这样做:

templateClonde = template.content.cloneNode(true);
Run Code Online (Sandbox Code Playgroud)

说明

我不知道为什么当 importNode() 抛出错误时 cloneNode() 不会抛出错误。我唯一的猜测是,如果克隆引用和附加的克隆在同一个 DOM 中,则不应使用 importNode()。

无论如何,如果有人能进一步解释这两种方法之间的区别,我会很高兴,但由于 OP 要求举个例子,这里是我的。