How would I go about removing all of the child elements of a DOM node in JavaScript?
Say I have the following (ugly) HTML:
&
The currently accepted answer is wrong about innerHTML
being slower (at least 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.
Here is what I usually do :
HTMLElement.prototype.empty = function() {
while (this.firstChild) {
this.removeChild(this.firstChild);
}
}
And voila, later on you can empty any dom element with :
anyDom.empty()
elm.replaceChildren()
It's experimental without wide support, but when executed with no params will do what you're asking for, and it's more efficient than looping through each child and removing it. As mentioned already, replacing innerHTML with an empty string will require HTML parsing on the browser's part.
Documentation here.
element.textContent = '';
It's like innerText, except standard. It's a bit slower than removeChild()
, but it's easier to use and won't make much of a performance difference if you don't have too much stuff to delete.
element.innerHTML = ""
(or .textContent) is by far the fastest solution
For example:
https://jsperf.com/innerhtml-vs-removechild/15
This test does not add new children to the element between each iteration. The first iteration will remove the element's contents, and every other iteration will then do nothing.
In this case, while (box.lastChild) box.removeChild(box.lastChild)
was faster because box.lastChild was null
99% of the time
Here is a proper test: https://jsperf.com/innerhtml-conspiracy
Finally, do not use node.parentNode.replaceChild(node.cloneNode(false), node)
. This will replace the node with a copy of itself without its children. However, this does not preserve event listeners and breaks any other references to the node.
let el = document.querySelector('#el');
if (el.hasChildNodes()) {
el.childNodes.forEach(child => el.removeChild(child));
}