“ innerHTML + = ...”vs“阑尾子节点(txtNode)”

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

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

  • 我猜两者都会导致 ‘ ReFlow’。
  • 据我所知,后者(附加一个文本节点)也会导致完全重新构建 DOM (正确吗?他们都这么做了吗?).
  • 前者似乎还有其他一些讨厌的副作用,比如导致以前保存的对我修改 innerHTML 节点的子节点的引用不再指向“当前 DOM”/“子节点的正确版本”。相比之下,在附加子元素时,引用似乎保持不变。为什么会这样?

我希望你们能帮我解释清楚,谢谢!

42686 次浏览

后者(appendChild)执行 没有,导致完全重新构建 DOM,甚至目标内的所有元素/节点。

前者(设置 innerHTML)确实会导致对目标元素的内容进行完全重新构建,如果您要添加这些内容,那么就没有必要了。

通过 innerHTML += content附加使浏览器运行元素中的所有节点,构建一个 HTML 字符串以赋予 JavaScript 层。然后,代码将文本附加到目标节点并设置 innerHTML,从而导致浏览器删除目标节点中的所有旧节点,重新解析所有这些 HTML,并构建新节点。因此,从这个意义上讲,它可能不是有效的。(然而,解析 HTML 是 浏览器的作用,而且他们真的非常非常快。)

设置 innerHTML的确会使对目标元素中的任何元素的引用失效——因为这些元素已经不存在了,所以在设置 innerHTML时删除它们并添加新的元素(它们看起来非常相似)。

简而言之,如果你是 附加,我会使用 appendChild(或者 insertAdjacentHTML,见下文)。如果要替换,有些情况下使用 innerHTML比自己通过 DOM API 创建树更好(速度是其中最重要的)。

最后,值得一提的是另外两个选择:

  • append 是对 DOM 的一个相对较新的补充(但是除了真正过时的浏览器之外,还有 很好的支持)。它将一个或多个项追加到元素,这些项可以是定义节点和元素的节点、元素或 HTML 字符串。与 appendChild不同,它支持 HTML 字符串和节点,并且还支持多个参数。对于您的用例,它没有列表中的下一个选项 parent.append(htmlString)那么麻烦。
  • insertAdjacentHTML 将以 HTML 字符串形式提供的节点和元素插入到元素中或元素旁边。您可以用它来附加一个元素: theElement.insertAdjacentHTML("beforeend", "the HTML goes here");第一个参数是放置 HTML 的位置; 您的选择是:
    • "beforebegin"(在元素之外,就在它的前面)
    • "afterbegin"(元素内部,开头)
    • "beforeend"(在元素内部,在末尾)
    • "afterend"(在元素之外,刚好在它之后) 请注意,"afterbegin""beforeend"插入到元素本身,而 "beforebegin""afterend"插入到元素的 家长中。浏览器支持 基本上是普遍的
  • insertAdjacentText insertAdjacentHTML类似,只是它插入了一个文本节点(文本不作为 HTML 处理)。浏览器支持 基本上是普遍的

我已经创建了一个小的 gist,其中包含 innerHTML 和阑尾 Child 之间的性能比较。

最后一个大幅领先

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