Remove all child elements of a DOM node in JavaScript

前端 未结 30 1390
花落未央
花落未央 2020-11-22 03:28

How would I go about removing all of the child elements of a DOM node in JavaScript?

Say I have the following (ugly) HTML:

&

相关标签:
30条回答
  • 2020-11-22 04:00

    If you use jQuery:

    $('#foo').empty();
    

    If you don't:

    var foo = document.getElementById('foo');
    while (foo.firstChild) foo.removeChild(foo.firstChild);
    
    0 讨论(0)
  • 2020-11-22 04:01

    Using a range loop feels the most natural to me:

    for (var child of node.childNodes) {
        child.remove();
    }
    

    According to my measurements in Chrome and Firefox, it is about 1.3x slower. In normal circumstances, this will perhaps not matter.

    0 讨论(0)
  • 2020-11-22 04:02
    var empty_element = function (element) {
    
        var node = element;
    
        while (element.hasChildNodes()) {              // selected elem has children
    
            if (node.hasChildNodes()) {                // current node has children
                node = node.lastChild;                 // set current node to child
            }
            else {                                     // last child found
                console.log(node.nodeName);
                node = node.parentNode;                // set node to parent
                node.removeChild(node.lastChild);      // remove last node
            }
        }
    }
    

    This will remove all nodes within the element.

    0 讨论(0)
  • 2020-11-22 04:05

    Option 1 A: Clearing innerHTML.

    • This approach is simple, but might not be suitable for high-performance applications because it invokes the browser's HTML parser (though browsers may optimize for the case where the value is an empty string).

    doFoo.onclick = () => {
      const myNode = document.getElementById("foo");
      myNode.innerHTML = '';
    }
    <div id='foo' style="height: 100px; width: 100px; border: 1px solid black;">
      <span>Hello</span>
    </div>
    <button id='doFoo'>Remove via innerHTML</button>

    Option 1 B: Clearing textContent

    • As above, but use .textContent. According to MDN this will be faster than innerHTML as browsers won't invoke their HTML parsers and will instead immediately replace all children of the element with a single #text node.

    doFoo.onclick = () => {
      const myNode = document.getElementById("foo");
      myNode.textContent = '';
    }
    <div id='foo' style="height: 100px; width: 100px; border: 1px solid black;">
      <span>Hello</span>
    </div>
    <button id='doFoo'>Remove via textContent</button>

    Option 2 A: Looping to remove every lastChild:

    • An earlier edit to this answer used firstChild, but this is updated to use lastChild as in computer-science, in general, it's significantly faster to remove the last element of a collection than it is to remove the first element (depending on how the collection is implemented).
    • The loop continues to check for firstChild just in case it's faster to check for firstChild than lastChild (e.g. if the element list is implemented as a directed linked-list by the UA).

    doFoo.onclick = () => {
      const myNode = document.getElementById("foo");
      while (myNode.firstChild) {
        myNode.removeChild(myNode.lastChild);
      }
    }
    <div id='foo' style="height: 100px; width: 100px; border: 1px solid black;">
      <span>Hello</span>
    </div>
    <button id='doFoo'>Remove via lastChild-loop</button>

    Option 2 B: Looping to remove every lastElementChild:

    • This approach preserves all non-Element (namely #text nodes and <!-- comments --> ) children of the parent (but not their descendants) - and this may be desirable in your application (e.g. some templating systems that use inline HTML comments to store template instructions).
    • This approach wasn't used until recent years as Internet Explorer only added support for lastElementChild in IE9.

    doFoo.onclick = () => {
      const myNode = document.getElementById("foo");
      while (myNode.lastElementChild) {
        myNode.removeChild(myNode.lastElementChild);
      }
    }
    <div id='foo' style="height: 100px; width: 100px; border: 1px solid black;">
      <!-- This comment won't be removed -->
      <span>Hello <!-- This comment WILL be removed --></span>
      <!-- But this one won't. -->
    </div>
    <button id='doFoo'>Remove via lastElementChild-loop</button>

    Bonus: Element.clearChildren monkey-patch:

    • We can add a new method-property to the Element prototype in JavaScript to simplify invoking it to just el.clearChildren() (where el is any HTML element object).
    • (Strictly speaking this is a monkey-patch, not a polyfill, as this is not a standard DOM feature or missing feature. Note that monkey-patching is rightfully discouraged in many situations.)

    if( typeof Element.prototype.clearChildren === 'undefined' ) {
        Object.defineProperty(Element.prototype, 'clearChildren', {
          configurable: true,
          enumerable: false,
          value: function() {
            while(this.firstChild) this.removeChild(this.lastChild);
          }
        });
    }
    <div id='foo' style="height: 100px; width: 100px; border: 1px solid black;">
      <span>Hello <!-- This comment WILL be removed --></span>
    </div>
    <button onclick="this.previousElementSibling.clearChildren()">Remove via monkey-patch</button>

    0 讨论(0)
  • 2020-11-22 04:06

    Here's another approach:

    function removeAllChildren(theParent){
    
        // Create the Range object
        var rangeObj = new Range();
    
        // Select all of theParent's children
        rangeObj.selectNodeContents(theParent);
    
        // Delete everything that is selected
        rangeObj.deleteContents();
    }
    
    0 讨论(0)
  • 2020-11-22 04:06

    Simplest way of removing the child nodes of a node via Javascript

    var myNode = document.getElementById("foo");
    while(myNode.hasChildNodes())
    {
       myNode.removeChild(myNode.lastChild);
    }
    
    0 讨论(0)
提交回复
热议问题