Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Remove all child elements of a DOM node in JavaScript

Tags:

javascript

dom

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

Say I have the following (ugly) HTML:

<p id="foo">     <span>hello</span>     <div>world</div> </p> 

And I grab the node I want like so:

var myNode = document.getElementById("foo"); 

How could I remove the children of foo so that just <p id="foo"></p> is left?

Could I just do:

myNode.childNodes = new Array(); 

or should I be using some combination of removeElement?

I'd like the answer to be straight up DOM; though extra points if you also provide an answer in jQuery along with the DOM-only answer.

like image 256
Polaris878 Avatar asked Oct 17 '10 20:10

Polaris878


People also ask

How do I remove all children from DOM?

Child nodes can be removed from a parent with removeChild(), and a node itself can be removed with remove(). Another method to remove all child of a node is to set it's innerHTML=”” property, it is an empty string which produces the same output.

How do I remove all DOM elements?

We can remove all the children elements of the DOM element by setting the innerHTML of the element to an empty string. The innerHTML property is used to set and get the HTML content within the element.

Will remove all child nodes of the set of matched elements from the DOM?

The empty() method removes all child nodes from the set of matched elements.


2 Answers

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>
like image 199
Gabriel McAdams Avatar answered Oct 09 '22 01:10

Gabriel McAdams


Use modern Javascript, with remove!

const parent = document.getElementById("foo") while (parent.firstChild) {     parent.firstChild.remove() } 

This is a newer way to write node removal in ES5. It is vanilla JS and reads much nicer than relying on parent.

All modern browsers are supported.

Browser Support - 97% Jun '21

like image 28
Gibolt Avatar answered Oct 09 '22 01:10

Gibolt