5

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

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

4

7 回答 7

8

这始终是一个有争议的论点,部分原因是innerHTML从标准的角度来看有点可疑。我认为 QuirksMode 文章仍然具有相关性,但我希望看到它得到更新。也许联系 ppk以更新它们,尽管我确定他很忙。我们都可以从我们在 Web 开发中所做的假设的性能测试中受益。到底索赔需要硬数据来证明,否则真的只是说说而已。

不管怎样,我做了一些搜索,发现了一些与这个讨论相关的有趣文章。我不记得以前听说过 DocumentFragments,它们真的很有趣。

于 2009-11-07T22:21:23.640 回答
4

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

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

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

根据您的情况(特别是:目标元素中已经有多少子节点,以及您要添加多少?)将操作分解为 DocumentFragment 上的较小操作可能会更快,其子节点可以附加到一个元素的子元素一口气而不是一个一个。这要快得多。不幸的是,无法innerHTML在 DocumentFragment 上进行设置。

使用 Range 对象一次移动大量 HTML 可能还有更快的 hack,但不幸的是,Range 是高度跨浏览器的变量。不过,在我看来,有人应该能够从 IE 的range.pasteHTML和 W3 的range.extractContents构建一个快速的 append-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,但它在这里的使用是显而易见的。)

于 2009-11-07T21:13:30.540 回答
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);

第一个示例将新创建的节点附加到已包含在主体内的节点上,因此每次都会进行刷新。

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

于 2012-11-20T06:57:01.340 回答
1

如果性能很重要,很高兴知道它innerHTML相对较快,尤其是在 MSIE 中:http ://www.quirksmode.org/dom/innerhtml.html

然而,它最初是“Microsoft 专有”属性和/或不是真正的“OO”的不良形象。

于 2009-11-07T20:11:10.273 回答
0

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

于 2009-11-07T20:08:58.660 回答
0

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

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

于 2009-11-07T20:09:55.143 回答
0

不同之处在于通过 DOM 创建节点是标准化的,而 innerHTML 只是一个事实上的标准。我读过innerHTML 可以更快。

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

于 2009-11-07T20:10:15.113 回答