Run multiple animations in sequence in jQuery without polluting the code

Asked

Viewed 342 times

2

I need that when one animation ends in jQuery, another begins. And this should be done in sequence (without running at the same time).

I saw it on a project where I work a code that does this, but I think it has a lot of callbacks.

var speed = 1000;
var cb = undefined;
$(function() {
  $('.item:eq(0)').animate({
    opacity: 1
  }, speed, function() {
    $('.item:eq(1)').animate({
      opacity: 1
    }, speed, function() {
      $('.item:eq(2)').animate({
        opacity: 1
      }, speed, function() {
        $('.item:eq(0)').animate({
          opacity: 0
        }, speed, function() {
          $('.item:eq(1)').animate({
            opacity: 0
          }, speed, function() {
            $('.item:eq(2)').animate({
              opacity: 0
            }, speed, function() {
              $.isFunction(cb) && cb();
            })
          })
        })
      })
    })
  })
});
.item {
  height: 30px;
  background: red;
  opacity: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul>
  <li class="item">item</li>
  <li class="item">item</li>
  <li class="item">item</li>
</ul>

In that case, if we had more than 3 items (suppose we had 20), I wouldn’t want to have to put 20 callbacks.

Questions are:

  • How could this code improve?
  • How can I do these sequential animations in jQuery (one waiting for the other)?
  • In this specific example I would do like this: http://jsfiddle.net/whoc1tpd/ -> this is what you are looking for?

  • You can answer like this, you get +1. That’s just what I need

3 answers

2

Are you looking for Promise ;).

And your problem has a well-known name, it’s called Callback Hell

  • I’ve never heard of that promise. Very good!

  • Dherik, that answer is "answer" when you put an example of how to use the files in this case. Although I find it unnecessary here, I will give +1 if [Dit] the answer with an example. If not I think this answer is a comment and not a response. :)

  • @Sergio, I intend to do this later, now I can’t. But I think it’s also an answer. It just isn’t as complete as a response with his code working with promise. I think someone will probably do this before me :)

  • @Dherik completes then when you can. There are still few answers to talk about Predomises and I think it would be interesting. As it is falls into the category of "answer only by link" and is invalid for the site. I’ll see you here later, see you soon!

  • @Sergio you’re right. I’ll do it today :).

  • @Dherik, I’m here to remind you :)

  • @Wallacemaxters, worse than I got home, I sketched the code, but there was no time to finish. Then I forgot...

Show 2 more comments

1

In this particular case, you can do it without even thinking about it. If I understand well you want to run the elements, showing them, and then run again hiding. So successively. So it would be something like this:

CSS:

.item {
    opacity: 0;
    transition: opacity .8s;
}
.mostrar {
    opacity: 1 !important;
}

Javascript

(function () {
    var speed = 1000;
    var items = document.querySelectorAll('ul li');
    var index = 0;

    function iterar() {
        setTimeout(iterar, speed);
        items[index].classList.toggle('mostrar');
        index++;
        if (index == items.length) index = 0;
    }
    iterar();
})();

jsFiddle: http://jsfiddle.net/whoc1tpd/

Using the classList.toggle native you can add/remove a class in an element. So I created a function iterar calling herself and going through the elements to give her or remove this class.

1

Here’s an example of how to solve:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<style type="text/css">
        .item {
            height: 30px;
            background: red;
            opacity: 0;
          }
    </style> 
</head>
<body>    
   
    <ul>
      <li class="item">item</li>
      <li class="item">item</li>
      <li class="item">item</li>
    </ul>
</body>
<script type="text/javascript">
    
    function abrir(i){
        if(i == 3){ // QUANTOS ELEMENTOS IRÁ CRIAR ?
            fechar(0);
        }
        else{
            console.log(i);            
            $('.item:eq('+i+')').animate({ opacity: 1 }, 1000, function() { 
                i = i + 1;
                abrir(i); 
            });            
        }        
    };
    
    function fechar(i){
        if(i == 3){ // QUANTOS ELEMENTOS IRÁ CRIAR ?
            return 0; 
        }
        else{
            console.log(i);            
            $('.item:eq('+i+')').animate({ opacity: 0 }, 1000, function() { 
                i = i + 1;
                fechar(i); 
            });            
        }
    };
    
    $(function() {
        abrir(0);                
    });
</script>  
</html>

  • Friend, I can not give +1 today :( . But I will not forget to give the deserved +1

Browser other questions tagged

You are not signed in. Login or sign up in order to post.