Question

I'm trying to prevent clicks on a list item while an animation is occurring. So at the top of my click handler, I want to do something like this:

if(!$(this).is(:animated)) {
    // handle click code here
}

Note the 'bang' (!) in the if statement above. I haven't tested, but I assume this will work. What I'm not sure of is whether '.is(:animated)' will return true when run against an element that is being animated via fadeIn() and fadeOut(). I know that jQuery has a .animate() function, and I assume :animated certainly works against elements animated using that function, but will it work with those using fadeIn() and fadeOut()? Thanks.

UPDATE: After some dramatic mis-posts, all seems well, and thanks to the reponders for all the great follow-ups and edits. In the end, I have found that, yes, :animated matches those elements animated using fadeIn() and fadeOut() because the jQuery source uses .animate() to achieve these effects. My final check was as originally posted:

if(!$(this).is(:animated)) {
    // handle click code here
}

..rather than using .not() as has been proposed in some instances (though I believe these will work as currently posted). Thanks again.

Was it helpful?

Solution

Yes, :animated will return true for any sort of animation that jQuery creates. It will also do it for any plugins that animate provided they use the jQuery animate function.

However, you can write your code just a pinch differently to make use of jQuery:

Edit The not function is not the opposite of is. It filters out nodes, but still returns a jQuery object which evaluates to true. To use the not function as I originally suggested, you would have to add .length to the test:

if( $(this).not(':animated').length ) {
    // Handle click code here
}

Otherwise, use the function as the OP originally posted:

if( !$(this).is(':animated')) {
    // Handle click code here
}

OTHER TIPS

:animate will match elements which have had fadeOut called.

If you look in the jQuery source, you'll see that fadeOut simply calls animate.
It's defined like this:

// Generate shortcuts for custom animations
jQuery.each({
    slideDown: genFx("show", 1),
    slideUp: genFx("hide", 1),
    slideToggle: genFx("toggle", 1),
    fadeIn: { opacity: "show" },
    fadeOut: { opacity: "hide" }
}, function( name, props ){
    jQuery.fn[ name ] = function( speed, callback ){
        return this.animate( props, speed, callback );
    };
});

You don't need to have the if statement in there at all. You can chain the .not(':animated') before your 'click code'.

As an example, these fades would only work if the div wasn't in the process of being animated, therefore getting rid of the nasty queue problem.

$('a#show_me').toggle(function() {
    $('div#the_money').not(':animated').fadeIn();
}, function() {
    $('div#the_money').not(':animated').fadeOut();
});

It would work the same for the .click() as well.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top