217

Is it possible to run two animations on two different elements simultaneously? I need the opposite of this question Jquery queueing animations.

I need to do something like this...

$('#first').animate({ width: 200 }, 200);
$('#second').animate({ width: 600 }, 200);

but to run those two at the same time. The only thing I could think of would be using setTimeout once for each animation, but I don't think it is the best solution.

Community
  • 1
  • 1
Jakub Arnold
  • 85,596
  • 89
  • 230
  • 327
  • I have a real problem when animating different CSS properties. This question looks old, and I put it in the JSFiddle, seems both approaches work. Is this still relevant? http://jsfiddle.net/AVsFe/ – valk Oct 21 '13 at 19:57
  • 3
    In current jquery, and I believe since jQuery 1.4, the above code does animate both simultaneously, since fx queues are attached to the element that you call .animate() on, not a global queue. – Chris Moschini Dec 05 '14 at 18:39
  • Erm... have you tried it? If you use the exact code that you have there, to my understanding of how `animate()` works, they should run simultaneously. – chaos Aug 09 '09 at 12:36
  • Here we go -http://jsbin.com/axata . Add /edit to see the code – Russ Cam Aug 09 '09 at 12:41
  • Above jsbin is dead. jsfiddle of same, that works: http://jsfiddle.net/b9chris/a8pwbhx1/ – Chris Moschini Dec 05 '14 at 18:52

7 Answers7

426

yes there is!

$(function () {
    $("#first").animate({
       width: '200px'
    }, { duration: 200, queue: false });

    $("#second").animate({
       width: '600px'
    }, { duration: 200, queue: false });
});
Lee Taylor
  • 7,761
  • 16
  • 33
  • 49
Joshua
  • 4,292
  • 1
  • 15
  • 2
  • 17
    Thanks for this, didn't know about that `queue` variable! – dotty Jul 01 '11 at 11:03
  • 4
    May I ask what is the purpose of passing a function to jQuery? – pilau May 05 '13 at 10:13
  • 13
    @pilau It will be executed when the document is ready. This is a shorthand for $(document).ready(function(){}); and enables you to put your javascript code before your element definition. – Raphael Michel May 08 '13 at 17:31
  • It works but from a performance perspective it is not the best solution, since inside jQuery it uses two different timers: is there a way to use the same timer with jQuery? – yodabar Jun 15 '13 at 22:16
  • 1
    yes, you can eater set queue to true/false, or give it a string (queue-name) this way, both animations use the same timer... – AlexK Oct 25 '13 at 11:09
  • I was using a callback function like this: }, 200, function(){ and if i try to replace to be like : }, { duration: 200, queue: false }, function(){ something is not working well. Any ideea? – Crisan Raluca Teodora Feb 10 '14 at 15:26
  • @CrisanRalucaTeodora You can do that, just use this way: { duration: 200, queue: false, done:function(){ //code to be executed after animation }} – ThePianist Feb 26 '14 at 09:38
  • 3
    How would you add an onComplete to this? – jmchauv Jul 07 '16 at 18:50
20

That would run simultaneously yes. what if you wanted to run two animations on the same element simultaneously ?

$(function () {
    $('#first').animate({ width: '200px' }, 200);
    $('#first').animate({ marginTop: '50px' }, 200);
});

This ends up queuing the animations. to get to run them simultaneously you would use only one line.

$(function () {
    $('#first').animate({ width: '200px', marginTop:'50px' }, 200);
});

Is there any other way to run two different animation on the same element simultaneously ?

Waseem
  • 209
  • 2
  • 2
10

I believe I found the solution in the jQuery documentation:

Animates all paragraph to a left style of 50 and opacity of 1 (opaque, visible), completing the animation within 500 milliseconds. It also will do it outside the queue, meaning it will automatically start without waiting for its turn.

$( "p" ).animate({
  left: "50px", opacity: 1
}, { duration: 500, queue: false }); 

simply add: queue: false.

user697709
  • 101
  • 1
  • 2
8

If you run the above as they are, they will appear to run simultaenously.

Here's some test code:

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script>
$(function () {
    $('#first').animate({ width: 200 }, 200);
    $('#second').animate({ width: 600 }, 200);
});
</script>
<div id="first" style="border:1px solid black; height:50px; width:50px"></div>
<div id="second" style="border:1px solid black; height:50px; width:50px"></div>
Andreas Grech
  • 105,982
  • 98
  • 297
  • 360
3

While it's true that consecutive calls to animate will give the appearance they are running at the same time, the underlying truth is they're distinct animations running very close to parallel.

To insure the animations are indeed running at the same time use:

$(function() {
    $('#first').animate({..., queue: 'my-animation'});
    $('#second').animate({..., queue: 'my-animation'});
    $('#first,#second').dequeue('my-animation');
});

Further animations can be added to the 'my-animation' queue and all can be initiated provided the last animation dequeue's them.

Cheers, Anthony

Borgboy
  • 640
  • 5
  • 6
  • If you also need to trigger animations _after_ a set of other animations have finished, here's an answer for that which relies on promises and may also be helpful: https://stackoverflow.com/a/35141159/4342230 – GuyPaddock Jul 16 '21 at 05:36
  • 1
    Also, @Borgboy, your answer didn't work for me. According to https://stackoverflow.com/a/1218485/4342230 the animation queue for each object is different. You'd have to queue up all the animations and then do a new jQuery query that encompasses all of the elements that have queued animations so you can call dequeue on the results so they start together. In other words, `$('#first, #second').dequeue()`. – GuyPaddock Jul 16 '21 at 05:48
  • @GuyPaddock - Yes, you are correct. I need to update my answer accordingly. It looks like this change occurred around jQuery 3.3.1 or thereafter. – Borgboy Jul 18 '21 at 00:45
2

See this brilliant blog post about animating values in objects.. you can then use the values to animate whatever you like, 100% simultaneously!

http://www.josscrowcroft.com/2011/code/jquery-animate-increment-decrement-numeric-text-elements-value/

I've used it like this to slide in/out:

        slide : function(id, prop, from, to) {
            if (from < to) {
                // Sliding out
                var fromvals = { add: from, subtract: 0 };
                var tovals = { add: to, subtract: 0 };
            } else {
                // Sliding back in
                var fromvals = { add: from, subtract: to };
                var tovals = { add: from, subtract: from };
            }

            $(fromvals).animate(tovals, {
                duration: 200,
                easing: 'swing', // can be anything
                step: function () { // called on every step
                    // Slide using the entire -ms-grid-columns setting
                    $(id).css(prop, (this.add - this.subtract) + 'px 1.5fr 0.3fr 8fr 3fr 5fr 0.5fr');
                }
            });
        }
  • 1
    Dead link, found it back at https://web.archive.org/web/20150101065437/http://www.josscrowcroft.com/2011/code/jquery-animate-increment-decrement-numeric-text-elements-value# – PhiLho Oct 22 '15 at 16:38
0

Posting my answer to help someone, the top rated answer didn't solve my qualm.

When I implemented the following [from the top answer], my vertical scroll animation just jittered back and forth:

$(function () {
 $("#first").animate({
   width: '200px'
}, { duration: 200, queue: false });

$("#second").animate({
   width: '600px'
}, { duration: 200, queue: false });
});

I referred to: W3 Schools Set Interval and it solved my issue, namely the 'Syntax' section:

setInterval(function, milliseconds, param1, param2, ...)

Having my parameters of the form { duration: 200, queue: false } forced a duration of zero and it only looked at the parameters for guidance.

The long and short, here's my code, if you want to understand why it works, read the link or analyse the interval expected parameters:

var $scrollDiv = '#mytestdiv';
var $scrollSpeed = 1000;
var $interval = 800;

function configureRepeats() {
   window.setInterval(function () {
       autoScroll($scrollDiv, $scrollSpeed);
   }, $interval, { queue: false });
};

Where 'autoScroll' is:

    $($scrollDiv).animate({
        scrollTop: $($scrollDiv).get(0).scrollHeight
    }, { duration: $scrollSpeed });

    //Scroll to top immediately 
    $($scrollDiv).animate({
        scrollTop: 0
    }, 0);

Happy coding!

EGC
  • 1,719
  • 1
  • 9
  • 20