Matheus Machado Matheus Machado - 2 months ago 15
CSS Question

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 throught the list items. Any help would be appreciated

Answer

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>