【问题标题】:Document.importNode VS Node.cloneNode (real example)Document.importNode VS Node.cloneNode(真实示例)
【发布时间】:2017-01-15 07:42:06
【问题描述】:

Document.importNode in specification

Node.cloneNode in specification

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

【问题讨论】:

  • 在现代浏览器中您可能看不到差异,(显然,它们是在不同的接口上定义的)。从历史上看,在 DOM 中,importNode 用于从不同文档中复制节点,而 cloneNode 用于在同一文档中复制节点,但 DOM4 取消了这种区别,因为这种区别没有任何用处。

标签: javascript html dom w3c


【解决方案1】:

Alohci 是对的:没有太大区别,因为 web compatibility forced the browsers to implicitly adoptNode() before inserting a node into another document

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

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

【讨论】:

    【解决方案2】:

    简单地说:

    element.cloneNode() 用于从当前document 克隆一个节点,例如,当您附加任何 DOM 元素(如template)时,使用影子 DOM。在那里你调用shadowDOM.appendChild(template.content.cloneNode(true)),其中template 是在你的HTML 中定义的<template> 的一个实例。在这里,您告诉 JS 从当前 DOM 中获取元素并将其附加到影子 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);
    

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

    【讨论】:

    • 我在网上看到很多代码示例使用importNode和模板内容而不是cloneNode...
    【解决方案3】:

    几个月前,我开始在课堂上学习 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>
    

    这是我一开始尝试运行的 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);
    }
    

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

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

    解决方案

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

    templateClonde = template.content.cloneNode(true);
    

    解释

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-04-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-11
      相关资源
      最近更新 更多