admin管理员组

文章数量:1183232

I have a gallery with a long list of thumbnails. To prevent the DOM to be filled up with nodes, I am reusing them. What is the best way to remove the nodes from the DOM (without using a library)?

Using innerHTML = "" will parse and create a new empty text node, but looping and removing child will cause reflows?

I have a gallery with a long list of thumbnails. To prevent the DOM to be filled up with nodes, I am reusing them. What is the best way to remove the nodes from the DOM (without using a library)?

Using innerHTML = "" will parse and create a new empty text node, but looping and removing child will cause reflows?

Share Improve this question edited Sep 12, 2017 at 16:00 T.J. Crowder 1.1m199 gold badges2k silver badges1.9k bronze badges asked Dec 10, 2012 at 10:10 user920041user920041 8
  • node.innerHTML = "" does not create a new empty node, instead it empties node. – Alvin Wong Commented Dec 10, 2012 at 10:15
  • If you are reusing them why are you trying to remove them. Are you trying to replace the thumbnail in a html element and if so just set the href attribute on the img element. – Bruno Commented Dec 10, 2012 at 10:24
  • I am pooling the nodes for later reuse. – user920041 Commented Dec 10, 2012 at 10:26
  • so innerHTML = "" does not create an empty text node? – user920041 Commented Dec 10, 2012 at 10:27
  • 1 @IntoTheVoid: "the application will not refresh, so to avoid memory problems I am trying to keep node creation to a minimum" FWIW, I would let the browser worry about memory management until/unless you have a actual, palpable problem to address. – T.J. Crowder Commented Dec 10, 2012 at 10:38
 |  Show 3 more comments

3 Answers 3

Reset to default 20

You have at least four options:

  1. Using innerHTML = "" as you've shown in the question. It will make sure the element on which you call it has no child nodes at all, and doesn't create any new nodes. It's specified and reliable cross-browser (although there's an IE bug that may or may not affect your code), and is probably fairly efficient.

  2. Using textContent = "", which is also specified and reliable cross-browser (IE9+) and, interestingly, IE11 (at least) doesn't seem to have the bug with textContent that it has with innerHTML. It also has the advantage of not requiring an HTML parser, where of course the string you give innerHTML is expected to be HTML. (Browsers may well have an optimization in place for when the string is blank, though.)

  3. You could use removeChild in a loop, but that involves potentially repeated function calls into the DOM:

    // assuming elm is the element
    while (elm.firstChild) {
       elm.removeChild(elm.firstChild);
    }
    
  4. You could replace the parent element with a clone omitting the children:

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

    Note that unlike the others, this will remove any event handlers on the parent element.

If I had to guess, I'd guess that textContent = "" would be fastest, at least if there are a lot of children. But performance usually doesn't matter, it's an extremely rare case where this will be the noticeably slow part of your code. If you run into a situation where it matters, test your actual code usihng each of the options in your target browsers and choose the one that works best.

People love synthetic benchmarks, but synthetic benchmarks are remarkably unreliable and sensitive to benchmark assumptions (such as the number of children being removed).

You can also just call node.replaceChildren() and it will empty the node. It's quick, clean, and makes your intention clear.

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

本文标签: What is the best way to empty a node in JavaScriptStack Overflow