在 JavaScript 中清空节点的最佳方法是什么

IT技术 javascript
2021-03-05 20:08:36

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

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

3个回答

你至少有四个选择:

  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 = ""会是最快的,至少在有很多孩子的情况下。但是性能通常无关紧要,这是一种极其罕见的情况,这将是您代码中明显缓慢的部分。如果遇到重要情况,请使用目标浏览器中的每个选项测试您的实际代码,然后选择最有效的选项。

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

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;
}

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