Removing HTML Element children with JavaScript
Just a quick fyi, but if you are doing work in JavaScript and need to dynamically remove all of the childNodes from a DOM element, make sure to do it with a while loop, and not a for loop.
For example, this is bad:
function removeChildrenFromNode(node)
{
if(node !== undefined &&
node !=== null)
{
return;
}
var len = node.childNodes.length;
for(var i = 0; i < len; i++)
{
node.removeChild(node.childNodes[i]);
}
}
Since, as soon as you remove one child, the length of node.childNodes is 1 smaller, and you will eventually access an index that does not exist (and get a JavaScript error / exception).
The correct way to do this is with a while loop with node.hasChildNodes, like so:
function removeChildrenFromNode(node)
{
if(node !== undefined &&
node !=== null)
{
return;
}
var len = node.childNodes.length;
while (node.hasChildNodes())
{
node.removeChild(node.firstChild);
}
}
I just spent quite a bit of time debugging this. In fact, I am pretty sure that this is why the Macromedia News Firefox extension does not currently work well in Firefox 1.5. The odd thing is that this was not an issue prior to Firefox 1.5 (at least not in the Firefox extension).
Anyways, just a little heads up of something to watch out for.
Thanks to everyone on the Firefox development forums for helping me track this down.






yeah, i ran into a similar issue: http://www.visible-form.com/blog/000178.html . Of cours, as someone pointed out in the comments to that post, since you are dealing with a tree structure, a better way would probably be to keep track of the highest removable element in the tree and remove that.
flashape
24 Jan 06 at 1:11 pm
Using reversed FOR loop is another solution to this problem, where you would write it as for (var i = len – 1; i >= 0; i++)
Tangent
24 Jan 06 at 1:44 pm
Mike,
Since the node.hasChildNodes() will always do an evaluation, you can also always do a decremental for() loop.
for( var i=len; i > -1; i– ){
node.removeChild(node.childNodes[i]);
}
This should be a little more efficient since you’re not always doing an evaluation. However, if you have any asynchronous events going on that could be adding to the DOM, the node.hasChildNodes() method would be sure to get all the elements.
Dan G. Switzer, II
24 Jan 06 at 1:57 pm
I wonder whether the most effective solution would not be :
for(var i = 0; i I wonder whether the most effective solution would not be :
for(var i = 0; i < len; i++)
{
node.removeChild(node.childNodes[0]);
}
or may be :
for(var i = 0; i < len; i++)
{
node.removeChild(node.firstChild);
}
Michel
25 Jan 06 at 5:37 am
>Since the node.hasChildNodes() will always do an evaluation, you can also always do a decremental for() loop.
one minor correction. It should be len – 1 like so:
[code]for( var i=len - 1; i > -1; i-- ){
node.removeChild(node.childNodes[i]);
}[/code]
(this is how i fixed the firefox extension).
mike chambers
mesh@adobe.com
mike chambers
25 Jan 06 at 9:25 am
>I wonder whether the most effective solution would not be :
Well, the issue is the use of len, since as soon as you remove something, len is not longer valid.
mike chambers
mesh@adobe.com
mike chambers
25 Jan 06 at 9:27 am
What about:
while(node.firstChild) node.removeChild(node.firstChild);
This removes the need to call `hasChildNodes()` every time nor do you have to keep referencing the `childNodes` collection (which is a live collection, so takes up some resources).
Mark Wubben
25 Jan 06 at 12:19 pm
Thanks for the code. I ended up with this function:
function removeChildrenRecursively(node)
{
if (!node) return;
while (node.hasChildNodes()) {
removeChildrenRecursively(node.firstChild);
node.removeChild(node.firstChild);
}
}
mwarden
14 Feb 06 at 11:33 am
There is a simpler way to remove all children from a node (named parent here):
while ( parent.hasChildNodes() ) { parent.removeChild(parent.firstChild); }
and you really don’t need to recursively remove the children : removing the parent is sufficient.
Sébastien Pierre
30 May 06 at 9:28 am
Thanks for the great tips, this was bugging me for the last hour or so. Deleting the parent is usually easier, but not always the best solution.
Chris L
2 Jun 06 at 8:34 am
Thanks – this saved me some agony!
jvvw
8 Jun 06 at 3:13 am
Hi Mike, Thanks for the post. I think you have a logic error in the beginning of your function. You want to return if then node is either null or undefined, and not exit if node neither undefined or null. I think you want this:
if(node == undefined || node == null) return;
…though it looks like Mark Wubben’s answer is the best.
Gus
21 Jun 06 at 4:43 pm
What if we do
node.innerHTML = “”;
Would it remove all the child nodes?
alternate
4 Jul 06 at 3:35 pm
This is much easier:
function removeChildrenFromNode(node)
{
if(node !== undefined &&
node !=== null)
{
return;
}
var nodes = node.childNodes;
for(var i = 0; i This is much easier:
function removeChildrenFromNode(node)
{
if(node !== undefined &&
node !=== null)
{
return;
}
var nodes = node.childNodes;
for(var i = 0; i < nodes.length; i++)
{
node.removeChild(nodes[i]);
}
}
This way all your nodes are copied to var nodes, so when you delete you don’t get out of reference and you can still use regular forwards for loop.
jk
10 Aug 06 at 3:16 pm
What about just doing this to clear node childs:
myNode.innerText=”;
Rui Nunes
22 Aug 06 at 1:49 am
Rui Nunes got it!
Thank you!
Netrunner
13 Sep 06 at 4:49 am
I was successfully able to delete nodes with the removeChild/ while loop as you suggested.
However, in my case I am adding/removing tr elements as you expand/collapse a tree structure. In firefox it is working perfectly, in IE after items are removed there seems to be blank white space added in there place which pushes all rows below down and looks awkward. Any ideas why IE is doing this?
thanks
Kari Chase
29 Sep 06 at 7:50 am
If you wanted to check what you are deleting you could use a for-in loop:
for(key in parentNode.childNodes){
if(parentNode.childNodes[key].nodeName == ‘IMG’){
parentNode.removeChild(parentNode.childNodes[key]);
}
}
Andrew
23 Oct 06 at 4:35 pm
Many thanks for this Mike, worked a treat.
Des
Des Traynor
20 Dec 06 at 9:11 am
people are stranger
emurhfkq
21 Jun 07 at 6:41 pm
Thanks! This was a big help!
jerrygarciuh
26 Jun 07 at 5:09 am
Just wondering, for this part …
if(node !== undefined && node !=== null)
…
Dont you want to return nothing if the values are null or undefined, so only proceed if have a valid node? aka
if(node == undefined && node == null)
return null;
//otherwise do while loop
Anyway in the orig code, ‘!===’ a javascript equality operator?
I know ‘!==’ is strict equality operator, is ‘!===’ a mistake? i guess doesnt matter if that line should be replaced.
Arian
2 Nov 07 at 5:35 am
DOM should work on all: IE, Firefox and Opera. I am using the one!
Bimal
18 Feb 08 at 1:33 am
I just thought you might want to know that I just got an error with the initial testing on the node variable in IE7 and Firefox, but it worked when I removed the following section:
if(node !== undefined && node !=== null) {
return;
Evan Bowling
14 Mar 08 at 9:34 am
I am doing this:
var removeChildren = function (node) {
while (node.hasChildNodes()) {
node.removeChild(node.firstChild);
}
};
and firefox keeps telling me:
node.hasChildNodes is not a function
Nick
22 Jul 08 at 7:20 am
Hi,
I am currently tracking memory leak bugs in Internet Explorer for a product. I wanted to point out that using innerHTML=”" can cause memory leaks and removing children can cause memory leaks if any child elements have event handlers. Googling these terms should yield enough results to get you started. Beware of methods that do not take this into account.
D3c1m4L
23 Sep 08 at 4:49 pm