Matheus Machado
Matheus Machado

Reputation: 15

Change class of elements in a list and loop

I'm having a bit of trouble with a script. I have the basic idea, but cannot translate it into code.

Here's what it's supposed to accomplish:

I am using Animate.CSS, and I have the following list:

<ul class="display" id="imagens-home">
  <li class="invisivel"><img src="img/teste/lanche-1.jpg/></li>
  <li class="invisivel"><img src="img/teste/lanche-2.jpg/></li>
  <li class="invisivel"><img src="img/teste/lanche-3.jpg/></li>
  <li class="invisivel"><img src="img/teste/lanche-4.jpg/></li>    
</ul>

I want to make a script that will:

  1. Remove the .invisivel (display:none) class from an item;
  2. Add the .fadeInLeft class to it;
  3. Stay visible for about three seconds;
  4. Replace .fadeInLeft with .zoomOut;
  5. Make the element hidden again;
  6. Repeat for next item on the list;

I managed to find a way to enable the FadeIn animation, then after it ends, enable FadeOut and make the div invisible again, with the following code:

$(document).ready(function() {
  var animationIn = 'animated fadeInLeft';
  var animationOut = 'animated zoomOut';
  var animationEnd = 'webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend';

  $('#imagens-home>li').each(function(){
    $(this).removeClass('invisivel').addClass(animationIn).on(animationEnd, function(){
      $(this).removeClass(animationIn).addClass(animationOut).on(animationEnd, function(){
        $(this).removeClass(animationOut).addClass('invisivel')
      });
    });
  });
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css" rel="stylesheet"/>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="display" id="imagens-home">
  <li class="invisivel">0</li>
    <li class="invisivel">1</li>
  <li class="invisivel">2</li>
    <li class="invisivel">3</li>    
</ul>

But I cannot find a way to make it loop through the list items. Any help would be appreciated

Upvotes: 1

Views: 188

Answers (1)

nem035
nem035

Reputation: 35481

If I understood you correctly, you want each element to animate completely, before the next one starts animating.

Instead of using a loop, which will start all the animations essentially in parallel, you can use a recursive function to iterate through the elements by animating the next one when the previous one is done animating.

var animationIn = 'animated fadeInLeft';
var animationOut = 'animated zoomOut';
var animationEnd = 'webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend';

function animate($items, idx) {
  if (idx >= $items.length) return; // no more items, stop animating 

  var $current = $items.eq(idx);
  $current.removeClass('invisivel').addClass(animationIn).on(animationEnd, function() {
    $current.removeClass(animationIn).addClass(animationOut).on(animationEnd, function() {
      $current.removeClass(animationOut).addClass('invisivel');
      animate($items, idx + 1); // try animating the next item
    });
  });
}

$(document).ready(function() {
  animate($('#imagens-home>li'), 0);
});
.invisivel {
  display: none;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css" rel="stylesheet" />

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="display" id="imagens-home">
  <li class="invisivel">0</li>
  <li class="invisivel">1</li>
  <li class="invisivel">2</li>
  <li class="invisivel">3</li>
</ul>

Upvotes: 1

Related Questions