Remove childElements one-by-one in pure JavaScript

314 views Asked by At

I have:

<div id="alerts">
    <div class="alert">alert 1</div>
    <div class="alert">alert 2</div>
</div>

and want to remove these alerts one-by-one after 4000 ms by an interval of 500 ms in pure JavaScript.

I have this:

window.onload = function(){
    alerts = document.getElementById( 'alerts' );
    if( alerts ){
        alert = alerts.getElementsByClassName( 'alert' );
        setTimeout( function(){
            for( var i=0; i < alert.length; i++ ){
                ( function( i ){
                    setTimeout( function(){
                        alerts.removeChild( alert[i] );
                    }, 500);
                }
                )(i);
            }
        }, 4000);
    }
}

I think this is not the right way of using setTimeout.

2

There are 2 answers

1
Arun P Johny On BEST ANSWER

The getElementsByClassName returns a live collection which means when a selected element is removed or changed in the dom the referred collection also changes.

So in your example when you start the alert has 2 elemnets, but when the first element is removed then alert will have only 1 element but you are referring to alert[1] which will be undefined.

So the solution will be is to remove the first element from the array.

window.onload = function() {
  var alerts = document.getElementById('alerts');
  if (alerts) {
    alert = alerts.getElementsByClassName('alert');
    setTimeout(function() {
      for (var i = 0; i < alert.length; i++) {
        (function(i) {
          setTimeout(function() {
            alerts.removeChild(alert[0]);
          }, i * 500); //need increasing timeouts
        })(i);
      }
    }, 4000);
  }
}
<div id="alerts">
  <div class="alert">alert 1</div>
  <div class="alert">alert 2</div>
</div>


But you can use setInterval() to solve this in a better way like

window.onload = function() {
  var alerts = document.getElementById('alerts');
  if (alerts) {
    var alert = alerts.getElementsByClassName('alert');
    setTimeout(function() {
      var interval = setInterval(function() {
        alerts.removeChild(alert[0]);
        if (!alert.length) {
          clearInterval(interval)
        }
      }, 1000);
    }, 3000);
  }
}
<div id="alerts">
  <div class="alert">alert 1</div>
  <div class="alert">alert 2</div>
</div>

0
AmmarCSE On

A simpler approach would be to use setInterval

window.onload = function() {
  alerts = document.getElementById('alerts');
  if (alerts) {
    alert = alerts.getElementsByClassName('alert');
    var interval = setInterval(function() {
      if (alert.length) {
        alerts.removeChild(alert[alert.length - 1]);
      } else {
        clearInterval(interval);
      }

    }, 4000);
  }
}
<div id="alerts">
  <div class="alert">alert 1</div>
  <div class="alert">alert 2</div>
</div>