一尘不染

“ innerHTML + =…”与“ appendChild(txtNode)”

javascript

问题是,比较使用innerHTML的隐含条件并将文本节点附加到现有节点。幕后发生了什么?

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

  • 我猜都是在引起“ ReFlow”。
  • 据我所知,后者(附加一个文本节点)也会导致DOM的完全重建(正确?他们都在这样做吗?)。
  • 前者似乎还有其他讨厌的副作用,例如导致先前保存的对子节点的引用指向我正在修改innerHTML的节点,不再指向“当前DOM” /“子节点的正确版本”。相反,在附加子代时,引用似乎保持不变。为什么是这样?

希望大家能帮我解决这个问题,谢谢!


阅读 360

收藏
2020-04-25

共1个答案

一尘不染

后者(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的位置;第二个参数是放置HTML的位置。您的选择是"beforebegin"(元素外部,在元素前面),"afterbegin"(元素内部,在开头),"beforeend"(元素内部,在结尾)和"afterend"(元素外部,在元素之后)。请注意,"afterbegin""beforeend"插入到元素本身,而"beforebegin""afterend"插入到元素的
。我不知道所有主流桌面浏览器都支持该设备有多么出色的移动支持(尽管我确信至少iOS Safari和Android
2.x及更高版本具有此功能),但是垫片很小。

2020-04-25