Rhecil Codes
Rhecil Codes

Reputation: 541

Loop through sequential animations using $.each and setInterval?

I have a set of divs:

<div class="alert-container">
  <div class="alert">alert 1 text</div>
  <div class="alert">alert 2 text</div>
  <div class="alert">alert 3 text</div>
</div>

I want to animate them one-by-one as follows:

  1. alert 1 slideInDown > wait 3s > alert 1 slideOutDown >
  2. alert 2 slideInDown > wait 3s > alert 2 slideOutDown >
  3. alert 3 slideInDown > wait 3s > alert 3 slideOutDown >
  4. repeat from [1]

The current state of my JS is as this:

$('.alert-container .alert').each(function(index) {

  $(this).addClass('animated slideInDown').show().one(animationEnd, function(){
    $(this).removeClass('animated slideInDown').addClass('animated slideOutDown').one(animationEnd, function(){
      $(this).removeClass('animated slideOutDown').hide();
    });
  });

});

I'm using animate.css, as can be seen by the classes being added, and this currently has the result of simultaneously animating all three .alert divs, which is what I expect. Now I just need to modify this to animate one-by-one, and repeat infinitely.

Even after reviewing other SO posts, I'm struggling to wrap my head around where to use setInterval and $.each in order to achieve the results I want, and whether I should be using an initialDelay variable based on index etc.

Please help. Many thanks.

Upvotes: 1

Views: 478

Answers (2)

Rhecil Codes
Rhecil Codes

Reputation: 541

If anyone wants to see the exact code implemented using vijayP's answer, here it is:

jQuery(document).ready(function($) {

  var alertArr = $(".alert-container .alert");
  var alertTime = 6500;
  var visibleAlert = 0;
  var animationEnd = 'webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend';

  // loop through array of alerts

  function loopAlerts(){
    if(visibleAlert < alertArr.length ) {
      animateAlert(visibleAlert);
      visibleAlert++
    } else {
      visibleAlert = 0;
      animateAlert(visibleAlert);
      visibleAlert++
    }
  }

  // alert slideInDown > wait 3s > slideOutDown

  function animateAlert(visibleAlert){

    var alert = alertArr[visibleAlert];

    $(alert).addClass('slideInDown').removeClass('hide').one(animationEnd, function(){
      $('.minor-alerts .marquee .alert').removeClass('slideInDown slideOutDown');
      setTimeout(function(){
        $(alert).addClass('slideOutDown').one(animationEnd, function(){
          $(alert).addClass('hide').removeClass('slideOutDown slideInDown');
        });
      }, 3000);
    });
  }

  setInterval(loopAlerts, alertTime);

});

Upvotes: 1

vijayP
vijayP

Reputation: 11502

You may try below code:

$(document).ready(function(){

    var slideArray = $(".alert-container > .alert");
    var slideTime = 3000; //3 seconds
    var currentSlideIndex = 0;
    setInterval(function(){
        if(currentSlideIndex < slideArray.length){
            animateSlide(currentSlideIndex);
            currentSlideIndex++;
        }
        else
        {
            currentSlideIndex = 0;
            animateSlide(currentSlideIndex);
        }
    },slideTime);

    function animateSlide(slideIndex){
        var slideObject = slideArray[slideIndex]; //get the slide object to animate

        $(slideObject).addClass('animated slideInDown').show().one(animationEnd, function(){
            $(slideObject).removeClass('animated slideInDown').addClass('animated slideOutDown').one(animationEnd, function(){
              $(slideObject).removeClass('animated slideOutDown').hide();
            });
        });
    }
})

Basically you can't directly use setInterval in $.each loop. So to avoid that approach you can animate one slide at a time by its index.

Note - I couldn't able to test above code. But I guess it should work.

Upvotes: 2

Related Questions