“innerHTML + = ...”vs“appendChild(txtNode)”

时间:2010-02-21 11:11:26

标签: javascript dom

问题是,使用innerHTML比较连接并将文本节点附加到现有节点。现场背后发生了什么?

到目前为止我对此的看法:

  • 我猜两个都是造成了 '回流'。
  • 后者(附加一个文本节点),据我所知,也会导致DOM的完全重建(对吗?他们都这样做吗?)。
  • 前者似乎有一些其他令人讨厌的副作用,比如导致以前保存的子节点引用到我正在修改innerHTML的节点,不再指向'当前DOM'/'正确版本的子节点' 。相比之下,在追加儿童时,参考文献似乎保持不变。这是为什么?

我希望你们有人能为我解决这个问题,谢谢!

2 个答案:

答案 0 :(得分:84)

后者(appendChild not 导致DOM的完全重建,甚至目标中的所有元素/节点。

前者(设置innerHTML)确实会导致目标元素内容的完全重建,如果你不需要追加,那就不需要了。

通过innerHTML += content追加使浏览器遍历元素中的所有节点,构建HTML字符串以提供给JavaScript层。然后,您的代码会向其附加文本并设置innerHTML,从而导致浏览器删除目标中的所有旧节点,重新解析所有HTML,并构建新节点。所以从这个意义上讲,它可能效率不高。 (但是,解析HTML是浏览器做什么而且它们真的非常非常快。)

设置innerHTML确实无效对您可能持有的目标元素中的元素的任何引用 - 因为这些元素不再存在,您删除它们然后放入新的元素(看起来非常相似)当你设置innerHTML时。

简而言之,如果你追加,我会使用appendChild(或insertAdjacentHTML,见下文)。如果你要替换,那么使用innerHTML比使用DOM API自己创建树更好(速度是其中的主要部分)是非常有效的情况。

最后,值得一提的是insertAdjacentHTML,这是一个可以用来使用HTML字符串将节点和元素插入到元素中或旁边的函数。您可以使用它附加到元素:theElement.insertAdjacentHTML("beforeend", "the HTML goes here");第一个参数是放置HTML的位置;你的选择是"beforebegin"(在元素之外,就在它前面),"afterbegin"(在元素内部,在开头),"beforeend"(在元素内部,在结尾处),和"afterend"(在元素之外,在它之后)。请注意,"afterbegin""beforeend"会插入元素本身,而"beforebegin""afterend"会插入元素的中。在所有主流桌面浏览器的支持下,我不知道移动支持有多好(虽然我确定iOS Safari和Android 2.x及以上版本都有),但the shim很小。

答案 1 :(得分:7)

我在innerHTML和appendChild之间进行了性能比较,创建了一个小小的要点。

最后一个获胜的是

https://gist.github.com/oliverfernandez/5619180