AlexBerd
AlexBerd

Reputation: 1504

JQuery: Wait until all fadeout`s of function are finished

I have next function:

function clearWorkingArea() {
     $('.extensionText').children('span').fadeOut(600, function() { $(this).remove() });
        $('ul.texts').fadeOut(600, function() { $(this).empty() });
        $('.buttonsDiv').fadeOut(600, function() { $(this).remove() });
        $('.processingDiv').fadeOut(600, function() { $(this).remove() });
}

I would like to call another function only after all animations in this function are finished. I tried :

 $.when(clearWorkingArea()).done(function() {...});

Also:

clearWorkingArea().promise().done(function() {...});

No luck, it is still not working properly. Is there is a way, instead of callback hell of fades, to do such function behavior?

Upvotes: 1

Views: 874

Answers (3)

Keith
Keith

Reputation: 24181

Update: just double checked jquery, animations can return a promise. I initially just did promise, but to get a promise with jquery you do promise(). So you don't need the helper function after all.

Below is an example.

Also if you have multiple selectors doing the same thing, you can combine. eg. below .two & .three fadeOut at 600ms, but I've made .one fadeOut over 1000ms. Also added a none-existent selector to make sure things still work.

Promise.all(
  [
    $('.one').fadeOut(1000, function () {
      $(this).empty(); }).promise(),
    $('.two,.three').fadeOut(600, function () {
      $(this).empty(); }).promise(),
    $('.not-exist').fadeOut(600, function () {
      $(this).empty(); }).promise()
  ]
).then(function () {
  console.log('all done');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="one">
Three  1000 ms
</div>
<div class="two">
One 600 ms
</div>
<div class="three">
Two  600 ms
</div>

Upvotes: 2

sjahan
sjahan

Reputation: 5940

clearWorkingArea only starts the animations, but these animations are all async. At the end of clearWorkingArea, your animations are unlikely to be over.

You have to fetch a promise for each animation and then use Promise.all to trigger your code when all promises are over.

According to the documentation, you can get the promise by using the start parameter in the options of fadeOut like methods: jQuery fadeOut()

Hope this helps!

Upvotes: 1

Thusitha
Thusitha

Reputation: 3511

How about we apply some simple logic like this.

function doWorkWhenAllFinished(counter) {
  if (counter == 4) {

    //All fade animations have been complete.
    //Good to go...    

  }
}


function clearWorkingArea() {
  var counter = 0;
  $('.extensionText').children('span').fadeOut(600, function() {
    counter++;
    $(this).remove();
    doWorkWhenAllFinished(counter);
  });
  $('ul.texts').fadeOut(600, function() {
    counter++;
    $(this).empty();
    doWorkWhenAllFinished(counter);
  });
  $('.buttonsDiv').fadeOut(600, function() {
    counter++;
    $(this).remove();
    doWorkWhenAllFinished(counter);
  });
  $('.processingDiv').fadeOut(600, function() {
    counter++;
    $(this).remove();
    doWorkWhenAllFinished(counter);
  });
}

Upvotes: 0

Related Questions