CSS-Tricks Example

Full Cycle of Animation on Hover/Off

Goals:

NOT Using .stop();

The smoothness of this is perfect, but the animations queue up.

$("div").hover(function(){
    $(this).animate({ width: "200px" });
}, function() {
    $(this).animate({ width: "100px" });
});

Using .stop(true, false);

Fairly smooth, but animations don't finish if you mouse off too quickly. These are also the default params. Also note that using .stop() on only one or the other doesn't help.

$("#endfalse div").hover(function(){
    $(this).stop(true, false).animate({ width: "200px" });
}, function() {
    $(this).stop(true, false).animate({ width: "100px" });
});

Using .stop(true, true);

Animations finish, but it's jerky.

$("#endtrue div").hover(function(){
    $(this).stop(true, true).animate({ width: "200px" });
}, function() {
    $(this).stop(true, true).animate({ width: "100px" });
});

Don't Queue

Not using stop at all, you can set the animiation to not queue, but it behaves the same as .stop(true, false)

$("#no-queue div").hover(function(){
    $(this).animate({ width: "200px" }, {queue: false});
}, function() {
    $(this).animate({ width: "100px" }, {queue: false});
});

Callback Test

Set a variable when animation is running, test for that variable before starting new animation, set it back during a callback event. Makes for some weird delayed queuing.

var inAnimation = new Array();

$("div").hover(function(){
    if (!inAnimation[$("div").index(this)] ) {
        $(this).animate({ width: "200px" });
    }
}, function() {
    inAnimation[$("div").index(this)] = true;
    $(this).animate({ width: "100px" }, "normal", "linear", function() {
        inAnimation[$("div").index(this)] = false; 
    })
});

Animated Test

Filter out elements currently being animated before starting new animation

$("#animate-test div").hover(function(){
    $(this).filter(':not(:animated)').animate({ width: "200px" });
}, function() {
    $(this).animate({ width: "100px" });
});

Dequeue

Test for presence of class (set upon hover and removed on mouseOut animate callback) before staring new animation. When new animation does start, dequeue.

$("div").hover(function(){
	if (!$(this).hasClass('animated')) {
		$(this).dequeue().stop().animate({ width: "200px" });
	}
}, function() {
    $(this).addClass('animated').animate({ width: "100px" }, "normal", "linear", function() {
		$(this).removeClass('animated').dequeue();
	});
});