【问题标题】:Adding DOM Elements, what is the Right Way?添加 DOM 元素,正确的做法是什么?
【发布时间】:2013-04-04 11:17:24
【问题描述】:

这个问题可能很愚蠢,也可能很简单。

谁能解释一下添加 DOM 元素的最佳方法是什么。我们有这两种添加 DOM 元素的方法。

场景:需要在现有的<div id="theEl"></div> 中添加<strong>Hi</strong>

  1. 通过编辑其中的 HTML。

    document.getElementById("theEl").innerHTML = '<strong>Hi</strong>';
    
  2. 通过使用document.createElement()

    var hi = document.createTextNode("Hi"),
    strong = document.createElement("strong");
    strong.appendChild(hi);
    mydiv = document.getElementById("theEl");
    document.body.insertBefore(strong, mydiv);
    

问题

  1. 最好的方法是什么?一个是单行,另一个大约是五行。
  2. 什么是性能方面?
  3. 什么是正确的方法或最佳做法?
  4. 代码整体有区别吗?

如果这个问题根本没有意义,请告诉我,我很乐意关闭它甚至删除它。谢谢。


更新

对于亲密的选民来说,这不会重复该问题。我刚刚注意到的一件事是,使用createElement() 保留了附加到元素的事件处理程序。尽管这是一个很好的观点,但任何类型的基本网页中也都有 jQuery,它提供了委托和其他东西,即使在 HTML 发生变化之后,我也可以将事件附加到元素上。


伙计们,请在近距离投票时保持冷静。一种研究。

【问题讨论】:

  • 我更喜欢方法 1 来进行简单的 HTML 插入。但是如果我必须使用循环生成一些节点,方法2可能更容易。
  • @KingKongFrog 感谢好友的链接! :)
  • 为了性能,innerHTML 要快得多quirksmode.org/dom/innerhtml.html
  • 无论如何,这里要考虑的不止一件事,这就是为什么我认为它是非建设性的;没有冒犯……只是这个问题应该涵盖更窄的范围。

标签: javascript html dom


【解决方案1】:

没有“最佳”或“最佳实践”。它们是添加具有不同特征的内容的两种不同方法。您选择哪一种取决于您的具体情况。

对于创建大量元素,一次设置一个 HTML 块通常比创建和插入大量单个元素更快。虽然如果您真的关心这方面的性能,您需要在 jsperf 之类的工具中测试您的特定情况。

对于创建具有大量精细控制的元素、从变量设置类、从变量设置内容等...,通常通过createElement() 更容易做到这一点,您可以直接访问每个元素的属性无需构造字符串。

如果您真的不知道这两种方法之间的区别,并且看不出在特定情况下使用其中一种方法的明显理由,那么请使用更简单且代码更少的方法。我就是这么做的。

回答您的具体问题:

  1. 没有“最佳”方式。选择最适合您的情况的方法。
  2. 您需要测试特定环境的性能。在某些情况下,通过使用 .innerHTML 设置一个大字符串而不是单独创建一个插入所有对象,大量 HTML 显示速度更快。
  3. 没有“正确方法”或“最佳实践”。请参阅答案 #1。
  4. 如果对这两种方法进行编码以创建相同的最终结果,则这两种方法创建的最终结果没有区别。

【讨论】:

  • 一般来说,通过对浏览器和 JavaScript 行为方式的理解,我们就不能猜出哪个性能更好吗?正如你所说,拥有代码块更糟糕,我同意。
  • @PraveenKumar - 当人们关心优化性能时,猜测绝不是一个好主意。您只需测量即可知道。我认为答案是“这取决于具体情况,也可能取决于浏览器”。
  • 是的,有点同意你的看法...... :)
【解决方案2】:

我实际上喜欢两者的结合:createElement 用于外部元素,因此您不会删除任何事件处理程序,innerHTML 用于该元素的内容,以方便和性能。例如:

var strong = document.createElement('strong');
strong.innerHTML = 'Hi';
document.getElementById('theEl').appendChild(strong);

当然,当您添加的内容更复杂时,这种技术会更有用;那么您可以正常使用innerHTML(外部元素除外),但您不会删除任何事件侦听器。

【讨论】:

  • 哈哈...这是一种新的和不错的... :)
【解决方案3】:

1。最好的方法是什么?一个是单行,另一个是大约五行。

这取决于上下文。根据经验,您可能希望谨慎使用innerHTML

2。性能方面是什么?

DOM 操作的性能明显优于 innerHTML,但浏览器似乎在不断提高 innerHTML 的性能。

3。什么是正确的方法或最佳做法?

参见#1。

4。代码整体有区别吗?

是的。 innerHTML 示例将替换现有元素的内容,而 DOM 示例将新元素放在旧元素旁边。您可能打算写mydiv.appendChild(strong),但这仍然不同。现有元素的子节点被追加而不是替换。

【讨论】:

  • 这是新的。我在这里有另一种看法:就性能而言,innerHTMLquirksmode.org/dom/innerhtml.html 快得多。你怎么看?
  • 我记得可能在一年前看过这些测试,并认为它们非常有偏见,并编写了自己的测试并获得了几乎我预期的结果。我认为这一切都记录在某处。
  • 很高兴获得该链接。 :)
  • @PraveenKumar,找不到它,但是看看这个:jsperf.com/w3c-dom-vs-innerhtml/10——注意除了“fastInnerHTML”测试之外,DOM 测试的性能优于innerHTML 测试,这在某种程度上是惊人的快,但它不是 innerHTML 的正常使用,可能不是 PPK 的想法。
  • @PraveenKumar,我认为测试过于复杂,不代表现实场景。如果我没记错的话,如果您插入一些从一个单元格到另一个单元格的虚拟数据,而不是仅仅插入星号,那么 PPK 的表格测试的表现就会大不相同。这是我不久前做的一个简单测试:jsperf.com/innerhtml-v-dom
【解决方案4】:

你说的最好是什么意思?仅在一次 DOM 操作中,一切都很好,并且表现出相同的性能。但是当你需要插入多个 DOM 时,情况就不同了。

背景

每次插入 DOM 节点时,浏览器都会渲染页面的新图像。因此,如果您在 DOM 节点中插入多个子节点,浏览器会多次呈现它。该操作是您将看到的最慢的操作。

解决方案

所以,我们需要一次追加大多数子节点。使用一个空的 dom 节点。内置是createDocumentFragment();

var holder = createDocumentFragment();
// append everything in the holder
// append holder to the main dom tree

真正的答案

如果是您所描述的情况,我更喜欢最短的解决方案。因为在一次 dom 操作中没有性能损失

【讨论】:

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