【问题标题】:Javascript innerHTML vs outerHTMLJavascript innerHTML 与 outerHTML
【发布时间】:2018-04-07 02:29:14
【问题描述】:

我有以下 javascript:

// create a new article tag
var elem = document.createElement('article');

// append the article to the comments list
document.querySelector('#comments-list').appendChild(elem);

我想设置文章的内容,并为其添加一些类,所以我正在研究两种方法:

// Option 1
// set the content using .innerHTML()
// and add the classes manually to the classList 
elem.innerHTML = "This is the comment";
elem.classList.add('comment'); 

// Option 2
// set the content and classes in one go using .outerHTML()
elem.outerHTML = "<article class='comment'>This is the comment</article>";

两者都很好用,但我注意到需要在将元素附加到 DOM 之前调用 .innerHTML,而在将元素添加到 DOM 之后需要调用 outerHTML

我更喜欢第二个选项,因为我实际上是在这个 javascript 文件中呈现 Rails 部分,并且有一个更可取的细微差别。

我的问题是这些技术中的一种是否比另一种更好?将元素添加到 DOM 之后再更改它的 HTML 是否有问题?或者从性能的角度来看,在写入 DOM 之前设置 innerHTML 是否更好?

【问题讨论】:

  • 嗯,你确实提到了,innerHTML 可以在元素未附加到 DOM 时设置,如果在操作期间不更新 DOM,大型操作往往会更快跨度>
  • setting outerHTML 是不必要的糟糕。只需使用elem.className="comment"
  • 这是个人意见,大多数个人意见会说设置 outerHTML 很糟糕
  • 使用内部 html 也不应该真正使用,而是创建
  • 一个文本节点并插入到文章元素中

标签: javascript


【解决方案1】:

根据 OP 问题、它的 cmets 和一个好的答案,在这种情况下,您最好使用 elem.outerHTML,因为您可以/可以在 Rails 中预先解析您的输入。

如果您要将决策转移到 JavaScript 端,良好的编码习惯将要求手动创建所有节点。如果您正在处理 100 个元素插入,那么您会注意到速度上的差异(如果您要对两种解决方案进行基准测试)。

【讨论】:

    【解决方案2】:

    取自 MDN 网站:

    innerHTML

    • Element.innerHTML 属性设置或获取描述元素后代的 HTML 语法。

    注意:如果 &lt;div&gt;&lt;span&gt;,&lt;noembed&gt; 节点有一个子文本节点 包括字符(&amp;), (&lt;),(&gt;)innerHTML 返回这些 字符分别为 &amp、&lt 和 &gt。使用Node.textContent 获取这些文本节点内容的正确副本。

    外部HTML

    element DOM 接口的outerHTML 属性获取描述元素及其后代的序列化 HTML 片段。可以设置为用从给定字符串解析的节点替换元素。

    innerHTMLouterHTML

    默认使用innerHTML。这将替换当前引用的元素内部的内容(如果使用即“=”)。如果您使用的是outerHTML,那么引用的元素被替换。

    演示:

    var h20 = document.getElementById("h20"),
        h21 = document.getElementById("h21");
    var ran = false;
    
    console.log("'h20' innerHTML (1) =", "'" + h20.innerHTML + "'", "outerHTML (1) =", "'" + h20.outerHTML + "'");
    console.log("'h21' innerHTML (1) =", "'" + h21.innerHTML + "'", "outerHTML (1) =", "'" + h21.outerHTML + "'");
    
    document.getElementById("button").onclick = evt => {
        if (ran) return false;
        
        h20.innerHTML = "<div>innerHTML</div>";
        h21.outerHTML = "<div>outerHTML</div>";
        
        console.log("'h20' innerHTML (2) =", "'" + h20.innerHTML + "'", "outerHTML (2) =", "'" + h20.outerHTML + "'");
        console.log("'h21' innerHTML (2) =", "'" + h21.innerHTML + "'", "outerHTML (2) =", "'" + h21.outerHTML + "'");
        
        ran = true
    }
    <button id="button">innerHTML vs. outerHTML</button>
    <br>
    <h2 id="h20"></h2>
    <h2 id="h21"></h2>

    【讨论】:

    • "这仅替换引用(原文如此)的当前元素内的内容(如果使用即“=”)。 - 这是不正确的 - 它会完全破坏并重新创建元素 - 因此它会破坏可能已在其上注册的任何事件处理程序等。
    • 没有你的声明“这仅替换当前元素内的内容(如果使用即“=”)引用(原文如此)。 - 唯一没有复制的部分 - 实际上是不正确的 - 它不仅替换了内容。它也破坏了容器。我将按我认为合适的方式投票 - 请随时“报告”您的任何感受。
    • @Fraser 不,不是吗? outerHTML 以 self 为目标,因此它也会在替换过程中销毁/替换 container (self)。 innerHTML 替换所有孩子,并且不破坏容器(自身)。如果您将事件处理程序添加到使用innerHTML 的元素,则事件处理程序将不会被销毁。它将继续工作,因为元素仍然存在。
    • 修改 innerHTML 会导致重新解析内容并重新创建 DOM 节点,从而丢失您附加的所有处理程序。
    • @Fraser 是的!但你不是在谈论内容!您指的是容器。当一个元素被替换/销毁时,它当然包括被重新解析和 DOM 节点!我没有说别的。
    【解决方案3】:

    我想说两者可能都不是你想要的,使用 textContent 或任何处理元素文本的属性。

    elem.textContent = "This is the comment";
    elem.classList.add("comment"); 
    

    innerHTML 将内容解析为 HTML 并完全销毁元素并重新创建它,它还销毁可能为该元素注册的任何事件处理程序等。使用outerHTML,元素集仍将保留对原始元素(如果有的话)的引用。

    因此,与设置文本内容的正确属性相比,两者都有可能的意外副作用。

    【讨论】:

    • 谢谢@Fraser,我现在正在使用 textContent。
    • 谢谢,这个答案在问题的上下文中更有意义。
    • @Fraser - 使用id=1 更改元素的innerHtml 仍会保留与该元素关联的处理程序,但outerHTML 会完全破坏这些处理程序?
    • @Fraser - 感谢您的回复。我的理解是,在元素上替换 innerHTML 将保留与特定元素关联的任何事件处理程序,而仅更改其内容。但是你好像在说不正确?
    • @BKSpureon - 是的,它破坏了元素,因此破坏了可能已在元素属性上设置的任何处理程序或其他数据。唯一的例外是保留的属性。见:stackoverflow.com/questions/5113105/…
    猜你喜欢
    • 1970-01-01
    • 2012-12-24
    • 2021-03-08
    • 2022-12-04
    • 2023-03-21
    • 1970-01-01
    • 2016-09-08
    • 2017-11-20
    • 2012-03-25
    相关资源
    最近更新 更多