替换HTMLElement的所有孩子?

Raw*_*ler 29 javascript dhtml

在我的代码中,我经常需要用新的子列表替换某个HTML容器的所有子容器.

最快的方法是什么?我目前的方法是将所有新元素收集到DocumentFragment中.我发现然后实际替换孩子的唯一方法是逐个删除所有孩子,并附加片段.有没有更快的方法?

注意:解决方案不需要跨浏览器,但最好不要求使用3d-party组件,如jQuery.目标设备是一个非常慢的CPU 上的WebKit,所以我需要完全控制任何回流.

Ste*_*fan 38

如果您只想替换所有孩子,关于类型,为什么不将其内容设置为''然后添加您的代码:

container.innerHTML = '';
container.appendChild( newContainerElements );
Run Code Online (Sandbox Code Playgroud)

这将基本上以最快的方式删除所有的孩子:)

  • 我们现在可以使用 `container.empty();` 代替 `container.innerHTML = ''` (4认同)
  • 尝试 `container.textContent = ''` 而不是 `innerHTML` (2认同)
  • @dkniffin 这是不久前的事了。我猜我指的是 [`empty()` jQuery 方法](https://www.w3schools.com/jquery/html_empty.asp#:~:text=The%20empty()%20method%20removes,使用%20the%20detach()%20方法),而不是普通的JS函数。(哎哟)也刚刚测试过..vanilla JS 似乎没有 `empty()` 函数 (2认同)

Mas*_*eed 15

2020 年更新 - 使用replaceChildren()API!

现在可以使用(跨浏览器支持)replaceChildren() API替换所有子项:

container.replaceChildren(...arrayOfNewChildren);
Run Code Online (Sandbox Code Playgroud)

这将同时执行以下两项操作:a)删除所有现有子项,以及b)在一次操作中附加所有给定的新子项。

您还可以使用相同的 API 来删除现有的子项,而不替换它们:

container.replaceChildren();
Run Code Online (Sandbox Code Playgroud)

这在 Chrome/Edge 86+、Firefox 78+ 和 Safari 14+ 中受支持。这是完全指定的行为。这可能比这里提出的任何其他方法都要,因为移除旧孩子和添加新孩子是 a) 不需要innerHTML,并且 b) 在一个步骤而不是多个步骤中完成。

  • **是的,确实如此。** 你[在 Safari 中尝试过](https://jsbin.com/kuqucid) 吗?效果很好。我提出了一个 [MDN 问题](https://github.com/mdn/browser-compat-data/issues/8145) 来纠正兼容性数据。 (4认同)
  • 另外,请不要编辑我的帖子,以免其准确性降低。我已经放回 Safari 14+。 (2认同)

Gib*_*olt 5

使用现代JS!直接使用remove而不是removeChild

while (container.firstChild) {
    container.firstChild.remove();
}
Run Code Online (Sandbox Code Playgroud)

或者:

let child;
while (child = container.firstChild) {
    child.remove();
}
Run Code Online (Sandbox Code Playgroud)

  • 仅当向后兼容性是且永远不会成为问题时才应使用此方法。我不认为代码是“现代”的,而是考虑“灵活性”的,如果我必须多输入几个字符来保留向后兼容性,为什么不呢..好习惯 (2认同)

The*_*ool 5

它不是直接解决问题,但在大多数情况下它是可用的,并且可能是更高效的方法之一。

您可以换出整个节点,而不是删除和填充其内容。

oldNode.parentElement.replaceChild(newNode, oldNode)
Run Code Online (Sandbox Code Playgroud)