创建/追加节点与innerHTML

发布于 2024-08-10 04:37:21 字数 126 浏览 5 评论 0原文

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

考虑到我需要插入几个标签,使用innerHTML似乎是有意义的。有人有不同的看法吗?

Does anyone have a good reason to use one over the other? As far as I can tell, create/append node simply prevents you from creating invalid code, while innerHTML allows you to inject multiple nodes at once.

Given that I need to insert several tags, it seems to make sense to use innerHTML. Does anyone have a different take?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

心的位置 2024-08-17 04:37:21

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

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

This is always a contentious argument, partially because the origin of innerHTML being somewhat dubious from a standards perspective. I think the QuirksMode article is still relevant, but I'd love to see it updated. Perhaps contact ppk about updating them, though I'm sure he's busy. We could all benefit from performance testing the assumptions we make in web development. In the end claims require hard data to prove, otherwise it's really just talk.

Anyway, I did some searching and found some interesting articles relevant to this discussion. I don't remember hearing of DocumentFragments before, they're real interesting.

黒涩兲箜 2024-08-17 04:37:21

考虑到我需要插入多个标签,使用innerHTML似乎是有意义的。

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

至于附加,你实际上没有任何选择。您无法在不丢失现有内容的情况下设置innerHTML,因此除非您对序列化和重新解析感到满意(这会清除任何不可序列化的数据,如表单内容、JavaScript 属性/引用和事件处理程序),否则您最终会设置另一个元素的innerHTML,并将每个子元素逐个移动。这就是许多框架所做的,它通常比手动创建和附加子项还要慢。

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

也可能有更快的方法使用 Range 对象来一次移动 HTML 负载,但不幸的是 Range 是高度跨浏览器变量。不过,在我看来,有人应该能够从 IE 的range.pasteHTML 和 W3 的 range.extractContents。有人愿意吗?

据我所知,创建/附加节点只是阻止您创建无效代码

潜在无效的标记不仅仅意味着您的应用程序在某些浏览器中中断。当您盲目地将 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,但它在这里的用途是显而易见的。)

Given that I need to insert several tags, it seems to make sense to use innerHTML.

Only ‘several’? Then speed is not an issue. It's when you're creating a hundred you have to think about what you're doing. It's not really the creating that's the problem, it's the child node list manipulation that gets slower and slower as you add each extra element.

As for appending, you don't really have any choice. You can't set the innerHTML without losing the existing content, so unless you're happy with serialising and re-parsing that (which wipes out any non-serialisable data like form contents, JavaScript properties/references and event handlers) you end up setting the innerHTML of another element and moving each child over one by one. This is what many frameworks do and it typically ends up even slower than manual create-and-appendChild.

Depending on your situation (specifically: how many child nodes are already in the target element, and how many are you going to add?) it can be faster to break down the operation into smaller manipulations on a DocumentFragment, whose children can be appended to an element's children all in one go instead of one-by-one. This is much faster. Unfortunately, it is not possible to set innerHTML on a DocumentFragment.

There may also be faster hacks using Range objects to move a load of HTML at once, but unfortunately Ranges are highly cross-browser variable. It seems to me, though, that someone ought to be able to build a fast append-html out of IE's range.pasteHTML and W3's range.extractContents. Anyone up for it?

As far as I can tell, create/append node simply prevents you from creating invalid code

Potentially invalid markup doesn't just mean your application breaks in some browsers. When you're blindly splicing together HTML without escaping like an idiot:

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

then you have a client-side cross-site-scripting security hole that is just as bad as a server-side one.

You can, of course, compromise, by creating the elements and setting their contents in separate steps. For example:

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 is not standard JavaScript, but its use here is obvious.)

冬天旳寂寞 2024-08-17 04:37:21

如果你使用这个技巧,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);

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

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

DOM MANIPULATION IS WAY FASTER IF YOU USE THIS TRICK!.

This is slow:

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

This is fast:

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

The first example appends the newly created node to a node that already is contained inside the body so a refresh is made each time.

The second example appends newly created nodes to a "buffer" node that is not inside the scope of the body, so no refresh is made until you place the buffer node inside the scope of the body. Try it yourself!.

月下凄凉 2024-08-17 04:37:21

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

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

If performance matters, it's good to know that the innerHTML is relatively fast, especially in MSIE: http://www.quirksmode.org/dom/innerhtml.html

It has however the bad image of originally being a "Microsoft proprietary" property and/or not really "OO".

書生途 2024-08-17 04:37:21

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

I believe that on certain platforms, you'll receive a performance boost using the DOM functions instead of innerHTML, as no expensive HTML parsing needs to be done.

原谅过去的我 2024-08-17 04:37:21

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

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

It depends on what your goal is.

Using DOM methods to insert html into a document will allow you to further manipulate those elements before / after inserting them.

嘦怹 2024-08-17 04:37:21

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

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

The difference is creating nodes via the DOM is standardized, but innerHTML is merely a de-facto standard. I've read that innerHTML can be faster.

An even better alternative is to use a library like jQuery for your DOM manipulation. It'll take care of most cross-browser incompatibilities and be more readable than using the DOM methods.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文