Reputation: 2211
In this example, I want to remove all the pararaphes. But as you can see, the for-loop below didn't remove them all, it still left the first paragraph for me. http://codepen.io/vinhnghi223/pen/jnkzh
article=document.getElementsByTagName("article")[0];
for (i=0; i<article.childNodes.length; i++) {
article.removeChild(article.lastChild);
}
However, if I change the code to i<4 (which is less than article.childNodes.length
), which returns 5, it works.
I got why article.childNodes.length
returns 5. It just confuses me because I think if it works with 4 then it should work with 5.
Upvotes: 0
Views: 102
Reputation: 700192
That's because you are changing the collection that you are looping through. You are looping from zero and up, and at the same time you are removing child nodes so that the upper limit of the loop is getting lower. In the middle your loop counter will meat the shrinking number of child nodes, and the loop ends.
For that loop to work, you would need to preserve the initial number of child nodes:
var cnt = article.childNodes.length;
for (i = 0; i < cnt; i++) {
article.removeChild(article.lastChild);
}
However, you can just loop while there are any child nodes left:
while (article.childNodes.length> 0) {
article.removeChild(article.lastChild);
}
Upvotes: 2
Reputation: 2975
It's because the .childNodes
collection updates with every removal. So the .length
is shrinking on every iteration, while i
is growing. Since you're removing the .lastChild
, you're going to end up meeting in the middle, and so the first half won't be removed.
When you hard code the original length, you eliminate the problem.
If your intent is to remove all the children, then just have the condition check to see if a .lastChild
exists.
while (article.lastChild) {
article.removeChild(article.lastChild);
}
"Live" node lists like this can be tricky, so you always need to be careful when modifying their elements in a loop.
Upvotes: 4