Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery adding functions to the animation queue

The problem is that when I try doing multiple animations they all happen the same time.
Is there any way to have animations go one after another without using callbacks?

Here's what I want to do:

$('#a1').click(function() { $('#div1').hide(3000); });
$('#a2').click(function() { $('#div2').hide(3000); });
$('#a3').click(function() { $('#div3').show(3000); });

If you click on #a1 and then click on #a2 then #a3 before the first animation completes then it shouldn't start right away but instead wait until the animation queue is empty then start the next one.

Take this demo for example

I want to be able to click a1 then a2 then a3 one after the another and first have it hide the first div completely, then the second completely, and then show the third.

My example is overly simple and while this can be done with callbacks, my real problem can't so callbacks aren't an option.

In essence, if you click all three the animation should complete in 9 seconds.

This DEMO should alert ('took around 9 seconds to complete')

like image 371
qwertymk Avatar asked Jun 03 '12 18:06

qwertymk


2 Answers

Use .queue() on a common jQuery object:

var q = $({}); // this could also be a common parent, e.g. $('body')
$('#a1').click(function() {
    q.queue(function(next) {
        $('#div1').hide(3000, next);
    });
    return false;
});
$('#a2').click(function() {
    q.queue(function(next) {
        $('#div2').hide(3000, next);
    });
    return false;
});
$('#a3').click(function() {
    q.queue(function(next) {
        $('#div3').show(3000, next);
    });
    return false;
});​

Demo

like image 114
Jeffery To Avatar answered Oct 24 '22 06:10

Jeffery To


Use .promise() to sidestep callbacks on show and hide:

The .promise() method returns a dynamically generated Promise that is resolved once all actions of a certain type bound to the collection, queued or not, have ended.

By default, type is "fx", which means the returned Promise is resolved when all animations of the selected elements have completed

Use .queue() to limit the number of animations resolved per promise (See also jsFiddle):

var promises = $({});

$('#a1').click(function() {
    promises.queue(function(next) {
        $('div').promise().done(function() {
            $('#div1').hide(3000);
            next();
        });
    });
    return false;
});
$('#a2').click(function() {
    promises.queue(function(next) {
        $('div').promise().done(function() {
            $('#div2').hide(3000);
            next();
        });
    });
    return false;
});
$('#a3').click(function() {
    promises.queue(function(next) {
        $('div').promise().done(function() {
            $('#div3').show(3000);
            next();
        });
    });
    return false;
});
like image 36
Ed I Avatar answered Oct 24 '22 06:10

Ed I