Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/448.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/210.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript &引用;innerHTML+;=&引用;vs";追加子项(txtNode)";_Javascript_Dom - Fatal编程技术网

Javascript &引用;innerHTML+;=&引用;vs";追加子项(txtNode)";

Javascript &引用;innerHTML+;=&引用;vs";追加子项(txtNode)";,javascript,dom,Javascript,Dom,问题是,使用innerHTML比较concatation和将文本节点附加到现有节点。幕后发生了什么 到目前为止,我对此的想法是: 我猜这两个都会导致 “回流” 据我所知,后者(附加一个文本节点)也会导致DOM的完全重建(正确吗?他们都这样做了吗?) 前者似乎还有其他一些令人讨厌的副作用,比如导致以前保存的对我正在修改innerHTML的节点的子节点的引用不再指向“当前DOM”/“子节点的正确版本”。相反,在附加子项时,引用似乎保持不变。为什么会这样 我希望你们能帮我澄清这件事,谢谢 后者(a

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

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

  • 我猜这两个都会导致 “回流”
  • 据我所知,后者(附加一个文本节点)也会导致DOM的完全重建(正确吗?他们都这样做了吗?)
  • 前者似乎还有其他一些令人讨厌的副作用,比如导致以前保存的对我正在修改innerHTML的节点的子节点的引用不再指向“当前DOM”/“子节点的正确版本”。相反,在附加子项时,引用似乎保持不变。为什么会这样
我希望你们能帮我澄清这件事,谢谢

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

前者(设置
innerHTML
)确实会导致完全重建目标元素的内容,如果要追加,则不需要这样做

通过
innerHTML+=content
进行追加,使浏览器在元素中的所有节点中运行,生成一个HTML字符串,以提供给JavaScript层。然后,您的代码向其追加文本并设置
innerHTML
,使浏览器删除目标中的所有旧节点,重新解析所有HTML,并构建新节点。因此,从这个意义上讲,它可能不是有效的。(然而,解析HTML是浏览器所做的事情,而且它们真的非常快。)

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

简而言之,如果要追加,我会使用
appendChild
(或
insertAdjacentHTML
,请参见下文)。如果您要替换,在一些非常有效的情况下,使用
innerHTML
比自己通过DOM API创建树更好(其中速度是最主要的)


最后,值得一提的是,这是一个可以使用HTML字符串将节点和元素插入到元素中或元素旁边的函数。您可以将它附加到元素:
theElement.insertAdjacentHTML(“beforeend”,“HTML在这里”)第一个参数是将HTML放在何处;您的选择是
“beforebeagin”
(在元素外部,就在元素前面)、
“afterbegin”
(在元素内部,在元素的开头)、
“beforebeand”
(在元素内部,在元素的末尾)和
“afterend”
(在元素外部,就在元素的后面)。请注意,
“afterbegin”
“beforeend”
插入元素本身,而
“beforebegin”
“afterend”
插入元素的父元素。受所有主要桌面浏览器的支持,我不知道移动支持有多好(尽管我确信iOS Safari和Android 2.x及以上版本至少有),但它很小。

我创建了一个小要点,其中比较了innerHTML和appendChild的性能

最后一个以很大的优势获胜


@TK:浏览器支持如何?一种技术比另一种技术更适用于旧浏览器和/或移动浏览器吗?@skaffman:在当今时代,我希望这两种技术都能在您使用的任何浏览器中使用
innerHTML
是非标准的,但几乎得到了普遍支持(让您了解一下,Prototype和jQuery都依赖于它)
appendChild
是最早一代的DOM级别的一部分,它将出现在那里。:-)请注意,
innerHTML
有一些限制和怪癖。例如,在某些浏览器上,不能通过设置TR元素的
innerHTML
来替换表行。IE会在你使用它的时候剥去领先的Whitespace。表单元素可能是一个挑战。等等。我的+1:-)我想说,如果你使用
innerHTML
,不要在循环中使用它。这样做效率很低,因为您要多次启动解析器。我见过类似(var I=0;I
的循环。相反,应该使用一个变量,并且应该在循环之外设置
innerHTML
,而我上面的语句已经过时了
innerHTML
已经标准化:@pyramation:设置
innerHTML
和读取它之间有很大的区别。正如我上面所说的,当您阅读它时,浏览器必须在所有节点之间旋转,以构建它们的HTML表示。在页面上添加新内容时,几乎总是最好添加一个元素并设置其
innerHTML
(因为浏览器基本上就是读取HTML字符串的)。但我绝不建议将
+=
innerHTML
一起使用。值得一提的是,这一要点表示在附加到现有
innerHTML
时的性能,而不是替换整个节点的内容。请永远不要使用innerHTML!在使用之前,请查看接受的答案。很久以前,FF在appendChild中有一个错误,导致元素中的selected在注入时未被选择,因此必须使用innerHTML,因为根据标记字符串构建DOM的HTML解析器没有相同的错误!