"innerHTML + = ..."vs"appendChild(txtNode)"

59 javascript dom

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

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

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

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

T.J*_*der 90

后者(appendChild)不会导致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及以上版本都有),但垫片很小.

  • @skaffman:在这个时代,我希望两者都能在你正在使用的任何浏览器中使用.`innerHTML`是非标准的,但几乎普遍支持(为了给你一个想法,Prototype和jQuery都依赖它).`appendChild`是最老一代DOM级别的一部分,它将会存在.:-)请注意,`innerHTML`存在限制和怪癖.例如,你不能通过在某些浏览器上设置TR元素的`innerHTML`来替换表行.IE将在您使用时删除前导空白.表单元素可能是一个挑战.等等. (6认同)
  • 来自我的+1 :-)我想说如果你使用`innerHTML`,不要在循环中使用它.这样做非常低效,因为您多次启动解析器.我见过像`for(var i = 0; i <arr.length; i ++){node.innerHTML + = arr [i]; }`.相反应该使用变量,并且应该在循环外设置`innerHTML`. (3认同)
  • 我上面的陈述已经过时了.`innerHTML`已经标准化:http://dev.w3.org/html5/spec/embedded-content-0.html#dom-innerhtml (3认同)

oli*_*rna 7

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

最后一个胜利很大

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