13

我有一个包含一长串缩略图的画廊。为了防止 DOM 被节点填满,我正在重用它们。从 DOM 中删除节点的最佳方法是什么(不使用库)?

使用innerHTML = ""将解析并创建一个新的空文本节点,但循环和删除子节点会导致回流?

4

3 回答 3

18

你至少有四个选择:

  1. innerHTML = ""如您在问题中所示使用。它将确保您调用它的元素根本没有子节点,并且不会创建任何新节点。它是指定且可靠的跨浏览器(尽管有一个 IE 错误可能会或可能不会影响您的代码),并且可能相当有效。

  2. 使用textContent = "",这也是指定和可靠的跨浏览器(IE9+),有趣的是,IE11(至少)似乎没有textContentinnerHTML. 它还具有不需要 HTML 解析器的优点,当然您提供的字符串应该innerHTML是 HTML。(不过,浏览器可能会对字符串为空时进行优化。)

  3. 您可以removeChild在循环中使用,但这涉及到 DOM 中可能重复的函数调用:

    // assuming elm is the element
    while (elm.firstChild) {
       elm.removeChild(elm.firstChild);
    }
    
  4. 您可以用省略子元素的克隆替换父元素:

    // assuming elm is the element
    const clone = elm.cloneNode(false);
    parent.parentElement.replaceChild(clone, elm);
    elm = clone;
    

    请注意,与其他人不同,这将删除父元素上的所有事件处理程序。

如果我不得不猜测,我猜这textContent = ""将是最快的,至少如果有很多孩子的话。但是性能通常并不重要,这是一种极其罕见的情况,这将是代码中明显变慢的部分。如果您遇到重要的情况,请使用目标浏览器中的每个选项测试您的实际代码,然后选择最有效的一个。

人们喜欢综合基准,但综合基准非常不可靠,并且对基准假设(例如被移除的儿童数量)非常敏感。

于 2012-12-10T10:13:45.253 回答
0
function clearNode(node, clone = true) {
  let emptyNode;

  if (clone) {
    emptyNode = node.cloneNode();
    node.parentNode.replaceChild(emptyNode, node);
    node = emptyNode;
  }
  else {
    while (node.hasChildNodes()) {
      node.removeChild(node.firstChild);
    }
    emptyNode = node;
  }

  return emptyNode;
}
于 2018-03-12T12:49:54.157 回答
0

您也可以只调用node.replaceChildren()它,它将清空节点。它快速,干净,并且使您的意图清晰。

于 2021-10-25T18:29:14.797 回答