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.
Answer
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 thaninnerHTML
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 uselastChild
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 forfirstChild
thanlastChild
(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 justel.clearChildren()
(whereel
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>