appendChild方法最容易被忽视的一个使用事项
提到
appendChild
方法,我们都知道它是用来将一个节点添加至指定DOM节点子集的末尾,最常见的应用场景就是我们通过document.createElement
方法新建一个DOM节点,然后使用appendChild
方法将新创建节点添加至指定节点子集的末尾。那它还有什么我们最容易被忽视的一个使用事项呢?
先从一段代码看起:
html部分:
<div class="div-1">
<div class="div-2">
<div class="div-3">
<div class="div-4"></div>
</div>
<div class="div-5"></div>
</div>
<div class="div-6"></div>
</div>
js部分:
let ele = document.querySelector('.div-1')
let child = ele.firstChild
let fragment = document.createDocumentFragment()
while (child) {
fragment.appendChild(child)
child = ele.firstChild
}
console.log(fragment)
上面代码想实现这样一个功能,由于后续需要频繁操作DOM元素,为了减少由于DOM元素被改变而引起重排等性能问题,就通过document.createDocumentFragment
方法创建一个虚拟的节点,然后将已渲染的DOM添加至该虚拟节点下方。打印结果如下:
appendChild
方法在插入节点时,如果被插入的节点已存在于文档树中时,在插入时会先在文档树中删除该节点,然后再将其插入到指定节点。
贴上MDN上关于appendChild
方法的说明:
上面这个规则就是本文的重头戏,是我们在使用appendChild
方法时最易忽略的一个规则,如果已经知道并理解appendChild
方法这个规则的,还是麻烦继续往下看(温故而知新^ _ ^)。
如果不知道上面这个规则时,则在看示例代码时,就会产生这样一个疑问:在while
循环中,child = ele.firstChild
不就是一直是同一个节点,这个循环是个死循环。但是当我们知道上面那个规则时,会发现每次appendChild
之后,ele
下面的节点就会少一个,此时child = ele.firstChild
就不再是同一个节点了,当循环结束后,ele
下方再无节点,如下图所示:
小结:
在使用appendChild
方法插入节点时,如果被插入的节点已存在于文档树中时,在插入时会先在文档树中删除该节点,然后再将其插入到指定节点。
参考文献
[1] Node.appendChild
[2] Node.firstChild
[3] 一道原生JS的问题