Remove all child elements of a DOM node in JavaScript
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.
Option 1 (much slower, see comments below):
var myNode = document.getElementById("foo");
myNode.innerHTML = '';
Option 2 (much faster):
var myNode = document.getElementById("foo");
while (myNode.firstChild) {
myNode.removeChild(myNode.firstChild);
}
The currently accepted answer is wrong about innerHTML being slower (atleast in IE and Chrome), as m93a correctly mentioned.
Chrome and FF are dramatically faster using this method (which will destroy attached jquery data):
var cNode = node.cloneNode(false);
node.parentNode.replaceChild(cNode ,node);
in a distant second for FF and Chrome, and fastest in IE:
node.innerHTML = '';
InnerHTML won't destroy your event handlers or break jquery references , it's also recommended as a solution here: https://developer.mozilla.org/en-US/docs/Web/API/Element.innerHTML
The fastest DOM manipulation method (still slower than the previous two) is the Range removal, but ranges aren't supported until IE9.
var range = document.createRange();
range.selectNodeContents(node);
range.deleteContents();
The other methods mentioned seem to be comparable, but a lot slower than innerHTML, except for the outlier, jquery (1.1.1 and 3.1.1), which is considerably slower than anything else:
$(node).empty();
Evidence here:
http://jsperf.com/innerhtml-vs-removechild/167 http://jsperf.com/innerhtml-vs-removechild/300 https://jsperf.com/remove-all-child-elements-of-a-dom-node-in-javascript (New url for jsperf reboot because editing the old url isn't working)
Jsperf's "per-test-loop" often gets understood as "per-iteration", and only the first iteration has nodes to remove so the results are meaningless, at time of posting there were tests in this thread set up incorrectly.
var myNode = document.getElementById("foo");
var fc = myNode.firstChild;
while( fc ) {
myNode.removeChild( fc );
fc = myNode.firstChild;
}
If there's any chance that you have jQuery affected descendants, then you must use some method that will clean up jQuery data.
$('#foo').empty();
The jQuery .empty()
method will ensure that any data that jQuery associated with elements being removed will be cleaned up.
If you simply use DOM
methods of removing the children, that data will remain.