Role of Callback and Chaining in jQuery ’s Animate & Effect


We know that chaining gives us a way to eliminate the use of temporary variables in programming. But here we will see another benefit with a Callback function.

In short, a Callback function (in it we can write other Callback functions for insider animate / effect) is executed only after the completion of the current animation.

We know that JavaScript is base on jQuery. So the code in jQuery will also excute in a line by line fashion. But it is not. The execution order of code in animation / effect methods get changed and it is not line by line. It means in animation, the next line of simple code is executed without waiting; the first one to complete.

The solution of this problem is Callback & Chaining.

Let's understand it with an example. Suppose we want our code to execute in the following order:

  1. Background color to - red
  2. Animation - opacity
  3. Giving alert message to user - animation done
  4. SlideUp
  5. Giving alert message to user - slideUp done
  6. SlideDown
  7. Giving alert message to user - slideDown done
  8. Background color to - blue
  9. Giving alert message to user - background color Restored

And to get it done we write the following code with:

Assumptions:
  1. A div with initial color: "blue" (<div style="background:blue;height:200px;width:250px;>)
  2. And a button on the page.
  3. jQuery code in <head> tag with <script> tag.

jQuery

$(document).ready(function(){ 
  $("button").click(function(){
    $("div").css("background-color","red");
    $("div").animate({"opacity" :0.5},"fast");
    $("div").slideUp();
    alert("slideUp done");
    $("div").slideDown();
    alert(" 'slideDown done");
    $("div").css("background-color","blue");
    alert(" background color Restored");
  });
});


So, see the output of the above code.
  1. Background color is changed
  2. You got alert saying -"slideUp done" though it is still not done.
  3. Again you get an alert (next alert) saying "slideDown done" though slideUp() is not executed and pending, because it is waiting to complete animate().
  4. Next an alert message says "background color Restored". Though except the alert statement, nothing is executed after animate().
  5. Now you see the effect of opacity while slideUp and just after a slideDown.

Surprise to see the execution order of code !!!

Is this was what we expected? No. So what we will do is to force the next line of code execution to stop until our animation is finished! And here a callback is useful.

Let's do one more exercise using Callback in animate():

$(" :button").click(function() {
    $("div").css("background-color", "red");
    $("div").animate({ "opacity": 0.5 }, "fast", "linear", function() {
        alert("animation done");
    });
    $("div").slideUp("normal", function() { alert("slide Up"); });

    $("div").slideDown("normal", function() { alert("slide Down"); });

    $("div").css("background-color", "blue");
    alert(" Background restored");
});


Again surprise !!!


This time the order of execution is as:

  1. Background color is changed to Red

  2. Background color is changed to blue

  3. Alert message 'Background restored'

  4. Animation is done & animation's callback function (alert message-'animation done')

  5. SlideUp is done & its Callback function (alert message -'slideUp done')

  6. SlideDown is done & its Callback function (alert message - 'slideDown done')

Why?

Actually we have just controlled our alert messages (of animate(), slideUp(), and slideDown() ) and at this time alert messages are coming only after the completion of animation/effect. But still it is not what we want as other lines like .css() are executing first and then the animations follow.

So, what else is wrong?

As I said that Callback function is executed after the completion of the current animation/effect. We need to place our code inside the Callback function and it would solve our problem.

Note the Chaining functionality of jQuery.

$(" :button").click(function(){
    $("div").css("background-color","red");
    $("div").animate({"opacity" :0.5},"fast","linear", function(){
            alert("animation done");
            $("div").slideUp("normal",function(){
                     alert("slide Up");
                    $("div").slideDown("normal",function(){
                        alert("slide Down");
                        $("div").css("background-color","blue");
                        alert(" Background restored");
                    } );
              } );
          });
      });
   });


Cheers!!!

At this time it is working fine.