0

Let's consider the following code

var ULs = document.getElementsByTagName('ul');
for(var i = 0; i < ULs.length; i++) {
 var ulLIs = ULs[i].getElementsByTagName('li');
 for(var n = 0; n < ulLIs.length; n++) {
  ulLIs[n].parentNode.removeChild(ulLIs[n]);
 }
}
<ul>
 <li>1-1</li>
 <li>1-2</li>
 <li>1-3</li>
 <li>1-4</li>
</ul>
<ul>
 <li>2-1</li>
 <li>2-2</li>
 <li>2-3</li>
 <li>2-4</li>
</ul>

As you see, JavaScript removes only even or odd childs. But I need remove all the childs.

How can I do it?

stckvrw
  • 1,689
  • 18
  • 42
  • Possible duplicate of [Why and when for loop ignore some item with html collection](https://stackoverflow.com/questions/26479289/why-and-when-for-loop-ignore-some-item-with-html-collection) – Sebastian Simon Jul 14 '18 at 10:47
  • If you want to remove all child then use `ULs[i].innerHTML = ''` no need of inner loop. – Durga Jul 14 '18 at 10:53

3 Answers3

1

When you remove an element in the inner loop, the index of its successors in the ulLIs list decreases by one, in particluar that of the next item to visit and delete. So it is referenced by the current index n. But for the next iteration this index is incremented.

Avoid this issue by counting backwards:

for (var n = ulLIs.length-1; n >= 0; n--) {
    ulLIs[n].parentNode.removeChild(ulLIs[n]);
} 

This SO answer provides two better solutions by re-setting the innerHtml of the list containers or repeatedly deleting the first child node until there is none.

collapsar
  • 17,010
  • 4
  • 35
  • 61
1

First thing as you are deleting the element from the start which is creating the problem as it is deleting the object which is not available.

var ULs = document.getElementsByTagName('ul');
for(var i = 0; i < ULs.length; i++) {
 var ulLIs = ULs[i].getElementsByTagName('li');
 for(var n = ulLIs.length-1; n >=0; n--) {
  ulLIs[n].parentNode.removeChild(ulLIs[n]);
 }
}
<ul>
 <li>1-1</li>
 <li>1-2</li>
 <li>1-3</li>
 <li>1-4</li>
</ul>
<ul>
 <li>2-1</li>
 <li>2-2</li>
 <li>2-3</li>
 <li>2-4</li>
</ul>

Second, why write much when you can do it in one line.

Array.prototype.forEach.call( element, function( node ) {
   node.parentNode.removeChild( node );
});

or

var myNode = document.getElementById("foo");
myNode.innerHTML = '';
Ullas Hunka
  • 2,119
  • 1
  • 15
  • 28
1

var ULs = document.getElementsByTagName('ul');
for(var i = 0; i < ULs.length; i++) {
 var ulLIs = ULs[i].getElementsByTagName('li');
 var n = ULs[i].getElementsByTagName('li').length;
 while(n--) {
  ulLIs[0].parentNode.removeChild(ulLIs[0]);
 }
}
<ul>
 <li>1-1</li>
 <li>1-2</li>
 <li>1-3</li>
 <li>1-4</li>
</ul>
<ul>
 <li>2-1</li>
 <li>2-2</li>
 <li>2-3</li>
 <li>2-4</li>
</ul>

It was happening because of the for loop. The one after the deleted one occupies the latter position. Hence they are skipped. So deleting the 0th element always of coming from the last will solve the problem.

Prajval M
  • 2,298
  • 11
  • 32