2009-11-07 50 views
5

有没有人有很好的理由使用其中一个?据我所知,创建/附加节点只是防止您创建无效的代码,而innerHTML允许您一次注入多个节点。创建/追加节点vs innerHTML

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

回答

8

这始终是有争议的说法,部分是因为innerHTML起源是从标准有点可疑透视。我认为QuirksMode文章仍然相关,但我很乐意看到它更新。也许contactppk关于更新他们,但我确信他很忙。我们都可以从性能测试中受益于我们在Web开发中所做的假设。最终,声称需要硬数据才能证明,否则这只是谈话而已。

无论如何,我做了一些搜索,并找到了一些有趣的文章与此讨论相关。我不记得以前听过DocumentFragments,他们真的很有趣。

+0

使用速度测试链接innerHTML与Win7上的片段: - Firefox 10.0.2两种方法的表现都差不多(每次都会稍微加快一点!) - Chrome(16.0.912.75米)innerHtml的速度始终快了50%。 – 2012-02-29 23:24:14

0

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

+0

根据此页面,innerHTML更快。 http://www.quirksmode.org/dom/innerhtml.html – Tmdean 2009-11-07 20:12:07

+0

@Tmdean:20个月很长。 – Gumbo 2009-11-07 20:18:36

+0

你知道是否有人做了更新的基准? – Tmdean 2009-11-07 20:22:50

0

这取决于你的目标是什么。

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

0

区别在于通过DOM创建节点是标准化的,但是innerHTML仅仅是一个事实上的标准。我读过innerHTML可以更快。

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

+1

您如何看待jQuery追加内容?很明显,你有信心,无论它做什么最好,但是看过代码后,我可以告诉你,它只是像其他人一样,执行相同的innerHTML解析和DOM节点追加,除了由于其错误的正则表达式而导致额外的错误 - 基于标记的黑客入侵。 – bobince 2009-11-07 21:16:05

1

如果性能问题,这是很好的知道innerHTML是比较快的,尤其是在MSIE:http://www.quirksmode.org/dom/innerhtml.html

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

+0

'innerHTML'在任何情况下都不是最快的。在Safari中DOM操作的平均时间为8ms,而innerHTML的平均时间为32ms。 – Gumbo 2009-11-07 20:16:55

+1

链接的文章是*位*旧的,Safari现在已经在4位。这可能有所不同。顺便说一句,我很好奇Chrome如何适应结果。众所周知,JS/DOM中速度非常快。 – BalusC 2009-11-07 20:27:37

4

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

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

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

根据您的情况(具体来说:目标元素中已有多少个子节点,以及要添加多少个子节点?)将操作分解为DocumentFragment上更小的操作可能会更快,子DocumentFragment的子级可以一次性添加到元素的所有子元素中,而不是逐个添加。这要快得多。不幸的是,不可能在DocumentFragment上设置innerHTML

使用Range对象同时移动一次HTML负载也可能会出现更快的黑客攻击,但不幸的是,范围是高度跨浏览器的变量。但在我看来,有人应该能够从IE的range.pasteHTML和W3的range.extractContents中构建一个快速附加HTML。有人知道吗?

至于我可以告诉大家,创建/添加节点简单地防止创建无效代码

可能无效的标记并不仅仅意味着在一些浏览器应用程序中断。当你盲目地拼接在一起,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,但在这里,它的用途是显而易见的。)

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

第一个例子追加新创建的节点到已经被包含在主体上的刷新是由每个内部节点时间。

第二个示例将新创建的节点追加到不在主体范围内的“缓冲区”节点,因此,只有将缓冲区节点放入主体范围内,才会进行刷新。亲自试一试!