代码之家  ›  专栏  ›  技术社区  ›  kakakali

为什么appendChild()会丢失一些子项?

  •  1
  • kakakali  · 技术社区  · 1 年前

    const div1 = document.createElement('div'),
        div2 = document.createElement('div')
    div1.innerHTML = '<br>x'
    div1.childNodes.forEach(child => {
        // text node x is missing
        console.log('child:', child)
        // magic line here
        div2.appendChild(child)
    })
    // finally, only <br> is seen
    console.log(div2.innerHTML)

    如图所示,文本节点 x 不见了。 如果是 appendChild() 这是有区别的,为什么它对待元素节点和文本节点不同?

    1 回复  |  直到 1 年前
        1
  •  1
  •   Robby Cornelissen    1 年前

    问题在于迭代,或者更具体地说,在迭代节点列表的同时修改节点列表。

    如上所述 MDN :

    注: 如果给定的子节点是对 文件 appendChild() 将其从当前位置移动到 新职位。

    在第一次迭代中,通过调用 div2.appendChild(child) <br> 节点,该节点已从 div1 以及 div1.childNodes 列表减少为一个(仅包含 x 文本节点)。然而,迭代指针已经移过了第一个元素,因此您 x 文本节点没有打印到控制台。

    如果你修改了一个循环使用的数组,你会看到完全相同的行为 forEach() :

    const array = ['<br>', 'x'];
    
    array.forEach((v) => {
      console.log(v);
      array.splice(0, 1);
    });