praveenjayapal
praveenjayapal

Reputation: 38529

How can I make a function wait until an animation completes?

I have used JQuery for a small animation work: a table #photos contains 9 photos and I would like to increase the width and height using the animate function on mouseover. But while the animation is running if the user moves to mouse to another photo it automatically triggers the next animation, so it's totally confused. What should I do? My code is:

$(function(){
  $("#photos tr td img").mouseover(function(){
    $(this).animate({"width":"1000px","height":"512px"},2000)
  });
  $("#photos tr td img").mouseout(function(){
    $(this).animate({"width":"100px","height":"50px"},2000)
  });       
});

Upvotes: 3

Views: 7092

Answers (5)

Amin Mousavi
Amin Mousavi

Reputation: 668

Always check queue animation of element and never get conflict from now:

$(function(){
  $("#photos tr td img").mouseover(function(){
    if($(this).queue("fx").length == 0)
       $(this).animate({"width":"1000px","height":"512px"},2000)
  });
  $("#photos tr td img").mouseout(function(){
       $(this).animate({"width":"100px","height":"50px"},2000)
  });       
});

Upvotes: 0

Doug Avery
Doug Avery

Reputation: 1057

I guess the answer depends on what you want to happen on the second mousover (while the first one is still animating).

1) If you want nothing to happen, you can have your first hover set an "animating" state on the whole TR, maybe like this:

  $tr = $(this).closest("tr");
  if ($tr.data("animating") != true) {
      $tr.data("animating",true);
      $(this)
        .stop(true,false)
        .animate({"width":"1000px","height":"512px"},2000, function(){
          $tr.data("animating",false);
      });
  }

2) If you want the original animation to end so your new image can animate, you'll need to .stop() the old one with the clearQueue and goToEnd parameters set to true. This will ensure that additional queued events (from a whole bunch of hovers) don't just keep happening for minutes, and it'll make the animation immediately skip to its final state:

  $(this).closest("tr").find("img:animated").stop(true,true);
  $(this).animate({"width":"1000px","height":"512px"},2000});

Upvotes: 1

MazarD
MazarD

Reputation: 2740

You should stop any running animation before starting a new one to avoid the mess up. It's probably the best and straightforward solution for this specific problem.

$(function(){
  $("#photos tr td img").mouseover(function(){
    $(this).stop();
    $(this).animate({"width":"1000px","height":"512px"},2000)
  });
  $("#photos tr td img").mouseout(function(){
    $(this).animate({"width":"100px","height":"50px"},2000)
  });       
});

Upvotes: 4

redsquare
redsquare

Reputation: 78667

In addition to the other answers I would look into using the hoverIntent plugin. This just avoids setting off a massive animation queue when the user sweeps the mouse over all photos. You only really want the animation if the user is actually hovered.

Upvotes: 1

Daff
Daff

Reputation: 44205

JQuery offers callbacks when the animation is complete. Then it might look like this for example:

var animating = false;
$(function(){ $("#photos tr td img").mouseover(
    function()
    {
        if(!animating)
            $(this).animate({"width":"1000px","height":"512px"},2000, easing, function() { animating = true; });
    }); 

    $("#photos tr td img").mouseout(
        function()
        {
            $(this).animate({"width":"100px","height":"50px"},2000, easing, function() { animating = false; }) 
        });
});

Upvotes: 6

Related Questions