0

I have a container div that contains some text and multiple divs all with class 'test', and I am trying to delete all the divs with class 'test' using pure javascript.

Currently, I have a variable containing all the divs with class 'test' which I have iterated through to remove each one.

var divsToRemove = document.getElementsByClassName("test");
for (var i = 0; i < divsToRemove.length; i++) {
  divsToRemove[i].remove();
}
<div id="container">
  <p>This text should stay</p>
  <div class="test">
    <p>Testing 1</p>
  </div>
  <div class="test">
    <p>Testing 2</p>
  </div>
  <div class="test">
    <p>Testing 3</p>
  </div>
  <div class="test">
    <p>Testing 4</p>
  </div>
</div>

I expected all of the divs with class 'test' to be removed, but only some of them have been removed with this code

j08691
  • 204,283
  • 31
  • 260
  • 272
richard2706
  • 45
  • 1
  • 6
  • 1
    `const removeElements = (elms) => elms.forEach(el => el.remove());` and use with `removeElements( document.querySelectorAll(".test") );` REFERENCE: https://stackoverflow.com/questions/4777077/removing-elements-by-class-name – GrafiCode Jun 18 '19 at 15:06
  • 1
    The key part is [getElementsByClassName](https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByClassName) returns a "_live_ HTMLCollection," which means as you remove elements from the DOM, your list changes in length, so iterating over it fails. [querySelectorAll](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll) returns a "_static (not live)_ NodeList," which can be safetly iterated over without the length of the list changing. – romellem Jun 18 '19 at 15:16

2 Answers2

2

getElementsByClassName() returns live HTMLCollection, you can try with querySelectorAll() which returns a static (not live) NodeList.

var divsToRemove = document.querySelectorAll(".test");
for (var i = 0; i < 4; i++) {
    divsToRemove[i].remove();
}
<div id="container">
   <p>This text should stay</p>
   <div class="test"><p>Testing 1</p></div>
   <div class="test"><p>Testing 2</p></div>
   <div class="test"><p>Testing 3</p></div>
   <div class="test"><p>Testing 4</p></div>
</div>
Mamun
  • 66,969
  • 9
  • 47
  • 59
1

As you're removing elements, the index of them changes, so start from the end and work to the front:

var divsToRemove = document.getElementsByClassName("test");
for (var i = divsToRemove.length-1; i >= 0; i--) {
  divsToRemove[i].remove();
}
<div id="container">
  <p>This text should stay</p>
  <div class="test">
    <p>Testing 1</p>
  </div>
  <div class="test">
    <p>Testing 2</p>
  </div>
  <div class="test">
    <p>Testing 3</p>
  </div>
  <div class="test">
    <p>Testing 4</p>
  </div>
</div>
j08691
  • 204,283
  • 31
  • 260
  • 272
  • This solution won't work in IE11 as it doesn't support ```remove``` method. [Related question](https://stackoverflow.com/questions/7561277/remove-an-element-from-the-dom-from-reference-to-element-only) [Caniuse](https://caniuse.com/#feat=childnode-remove) – Evghenii Jun 19 '19 at 15:32