创建/追加节点vs innerHTML

时间:2009-11-07 20:03:53

标签: javascript insert append innerhtml

有没有人有充分理由使用其中一个?据我所知,create / append节点只是阻止你创建无效代码,而innerHTML允许你一次注入多个节点。

鉴于我需要插入几个标签,使用innerHTML似乎是有意义的。有没有人有不同的看法?

7 个答案:

答案 0 :(得分:8)

这始终是一个有争议的论点,部分原因是innerHTML的起源在标准方面有点可疑。我认为QuirksMode文章仍然相关,但我很乐意看到它更新。也许contact ppk关于更新它们,尽管我确定他很忙。我们都可以从性能测试中受益于我们在Web开发中所做的假设。最后声明要求硬数据证明,否则它只是说话。

无论如何,我做了一些搜索,发现了一些与此讨论相关的有趣文章。我不记得之前听过DocumentFragments,它们真的很有趣。

答案 1 :(得分:4)

  

鉴于我需要插入几个标签,使用innerHTML似乎是有意义的。

只有'几个'?那么速度不是问题。当你创造一百个时,你必须考虑你正在做的事情。实际上并不是创建问题,而是在添加每个额外元素时,子节点列表操作变得越来越慢。

至于追加,你真的没有任何选择。你不能在不丢失现有内容的情况下设置innerHTML,所以除非你对序列化和重新解析它(消除任何非可序列化的数据,如表单内容,JavaScript属性/引用和事件处理程序)感到满意,否则你最终会设置另一个元素的innerHTML并逐个移动每个子元素。这是许多框架所做的事情,它通常比手动create-and-appendChild更慢。

根据您的具体情况(具体而言:目标元素中已有多少个子节点,以及您要添加多少个?)将DocumentFragment的操作分解为更小的操作可能会更快,其子项可以一次性附加到元素的子节点而不是一个接一个。这要快得多。遗憾的是,无法在DocumentFragment上设置innerHTML

使用Range对象一次移动大量HTML也可能有更快的黑客攻击,但遗憾的是Ranges是高度跨浏览器的变量。不过,在我看来,有人应该能够从IE range.pasteHTML和W3 range.extractContents中建立一个快速附加html。有人为此而努力吗?

  

据我所知,create / append节点只是阻止你创建无效代码

潜在的无效标记并不仅仅意味着您的应用程序在某些浏览器中会中断。当你盲目拼接HTML而不像白痴一样逃避时:

element.innerHTML= '<a href="'+url+'">'+title+'</a>';

然后你有一个客户端跨站点脚本安全漏洞,就像服务器端漏洞一样糟糕。

当然,您可以通过创建元素并在单独的步骤中设置其内容来妥协。例如:

element.innerHTML= '<table>'+'<tr><td>X</td><td><a href="#">go</a></td></tr>'.repeated(urls.length)+'</table>';
for (var i= 0; i<urls.length; i++) {
    var row= element.firstChild.rows[i];
    row.cells[0].firstChild.data= urls[i];
    row.cells[1].firstChild.href= urls[i];
}

(string.repeated不是标准JavaScript,但在这里使用是显而易见的。)

答案 2 :(得分:3)

如果你使用这个窍门,那么DOM操作会更快!

这很慢:

var target = document.getElementById('whatever');
for (a = 0; a<10000; a++) { 
var newnode = document.createElement('div'); 
newnode.textContent = a;
target.appendChild(newnode) }

这很快:

var target = document.createElement('span')
for (a = 0; a<10000; a++) { 
var newnode = document.createElement('div'); 
newnode.textContent = a;
target.appendChild(newnode) }
document.getElementById('whatever').appendChild(target);

第一个示例将新创建的节点附加到已包含在正文中的节点,以便每次都进行刷新。

第二个示例将新创建的节点附加到不在正文范围内的“缓冲区”节点,因此在将缓冲区节点放在正文范围内之前不会进行刷新。亲自尝试!。

答案 3 :(得分:1)

如果表现很重要,最好知道innerHTML相对较快,特别是在MSIE中:http://www.quirksmode.org/dom/innerhtml.html

然而,它原本是“微软专有”财产和/或不是真正的“OO”的坏形象。

答案 4 :(得分:0)

我相信在某些平台上,使用DOM函数而不是innerHTML会获得性能提升,因为不需要进行昂贵的HTML解析。

答案 5 :(得分:0)

这取决于你的目标。

使用DOM方法将html插入文档将允许您在插入之前/之后进一步操作这些元素。

答案 6 :(得分:0)

不同之处在于通过DOM创建节点是标准化的,但innerHTML仅仅是事实上的标准。我已经读过innerHTML可以更快。

更好的选择是使用像jQuery这样的库来进行DOM操作。它将处理大多数跨浏览器的不兼容性,并且比使用DOM方法更具可读性。