Fully Executing jQuery Animations Without Queuing

It is pretty common when using jQuery’s .animate() function that it is triggered by a mouseEnter or hover event. That’s all well and good, but it means that we need account for those events being triggered multiple times. If the element with the hover event attached is hovered over multiple times, that means the animation will be fired of several times, which is typically undesirable. The standard way to deal with this is using the .stop() function, like:

$(this).stop().animate({ width: "200px" });

This is definitely not the cure-all solution though. So let’s explore.

We already know that not using .stop() is problematic, because then the animations queue up and it is kind of awkward with multiple quick hovers. But not using .stop() is also kind of perfect in a way, because the mouseEnter animation and mouseLeave animation execute completely and sequentially. It is that smoothness that I am after here, only without the queuing.

Using .stop() prevents the queuing, but it also prevents the animations from completing a full cycle. Mouse off, the stop function fires, and stops the animation that triggered on mouseEnter and begins the animation resetting things.

The first thing I started messing with was in using .stop() prior to only one or the other of the animations, but that doesn’t help much. The .stop() function also has some parameters you can pass, the second of which dictates if the animation should be forced to complete first. If set to true, the animation will indeed finish, but it doesn’t do so smoothly, it jerks to it’s final state, which I find generally undesirable.

The solution lies in not beginning a new animation until the state of the element is not being animated. In that way, you don’t even need to worry about queuing, because only one animation can be running at a time anyway. There are a couple of ways to get there, but this I found the cleanest:

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

There was plenty of ideas on the journey here. Check out the demo below to see all the different options I went through, as well as an additional method that also works.

View Demo

  1. April 24, 2010 at 11:01 am

    In it something is. I agree with you, thanks for an explanation. As always all ingenious is simple.

  2. June 2, 2010 at 3:58 am

    I agree with most of what is said here.

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: