views:

396

answers:

4

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)
  });       
});
+4  A: 

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; }) 
     });
});
Daff
+2  A: 

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)
  });       
});
MazarD
except you might as well chain em. $(this).stop().animate(...) and use "hover"
Mark
A: 

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.

redsquare
+1  A: 

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});
Doug Avery