2

Some related questions I found from searching:

How does the 'fx' queue in jquery auto start?

What are queues in jQuery?

I've read through the documentation on animate() for jquery but I am having some difficulty figuring out a solution to my problem.

What I am looking to do is queue up a series of animations on multiple elements. I want the animations to act in sequence, that is I want the current animation on an element to block animations on its own element, but not block animations on the other element.

Finally I want to be able to cancel the animations on one of the elements but allow the animations on the other(s) to continue.

I think that named jquery queues is what I want, however attempting that gave me animations that never started (I think this is due to the magic that is the 'fx' queue not being present on every other queue).

Thanks in advance!

EDIT:

Here's what I am kind-of looking for:

function someAnimationWrapper(queueName, element, animation) {
    ///<summary>
    /// Places the animation specified into the queue of animations to be
    ///  run on that element.  The animation queue is a named queue so 
    ///  animations in the queue can be stopped at any time.
    ///</summary>
    ///<param name="queueName" type="String">
    /// The name to assign to the element's animation queue.
    ///</param>
    ///<param name="element" type="jQuery">
    /// jQuery object to perform the animations on.
    ///</param>
    ///<param name="animation" type="Object">
    /// Animation properties for the animation call.
    ///</param>

    // TODO: If magic needs to be done here this is a placeholder
    element.animate(animation);
}

function magicallyStopMyQueue(queueName, clearQueue, jumpToEnd) { // May take element, whatever I need to get the job done
    ///<summary>Mirrors jQuery.prototype.stop(), but with the named queue.</summary>
    ///<param name="queueName" type="String">
    /// Animation queue to stop.
    ///</param>
    ///<param name="clearQueue" type="Boolean">
    /// See jQuery.prototype.stop()
    ///</param>
    ///<param name="jumpToEnd" type="Boolean">
    /// See jQuery.prototype.stop()
    ///</param>

    // TODO: some magics here
}

var e1 = $('.myDiv1'),
    e2 = $('.myDiv2');

someAnimationWrapper('firstQueue', e1, { properties: { left: '-=16' }, duration: 100 });
someAnimationWrapper('firstQueue', e1, { properties: { left: '-=16' }, duration: 100 });
someAnimationWrapper('firstQueue', e1, { properties: { left: '-=16' }, duration: 100 });
someAnimationWrapper('secondQueue', e2, { properties: { left: '-=16' }, duration: 100 });
someAnimationWrapper('secondQueue', e2, { properties: { left: '-=16' }, duration: 100 });
someAnimationWrapper('secondQueue', e2, { properties: { left: '-=16' }, duration: 100 });

// Now I want to stop the first one
magicallyStopMyQueue('firstQueue', true, true);
Community
  • 1
  • 1
anthony sottile
  • 61,815
  • 15
  • 148
  • 207
  • @Beetroot-Beetroot : By block I mean the other animations do not start until the current animation in the queue is finished. I'll see if I can clarify with code. – anthony sottile Jun 19 '12 at 02:07

2 Answers2

1

I'll just take a shot in the dark here.

You want to queue multiple animations to fire one after the other, we use callback functions to do this. Callback Functions will never run until the parent event has finished. In this case, it's animations.

You can find the working example of the code (to follow) located here.

The code:

$('.a').animate({
  //This fires immediately
  left:"+=50px"     
}, function(){
  /* 
   *Reference name for Example:
   *cb1
   */
  //This fires once the above has been completed.
  //we also don't want the animation to fire on some eleents.
  $('.a').animate({
    left:"-=50px"
  }, function(){
    $('.b').animate({
      /* 
       *Reference name for Example:
       *cb2
       */
      //even though we stop it below AND clearQueue..
      //this will still run in the callback.
      left:"-=75px"
    });              
  });
  //This will only stop the initial callback function (@ cb1)
  //The function in the callback (@cb2) will fire once it has completed.
  $('.b').stop(true);
});

Hopefully this sheds some insight into chaining animations and allows you to move forward, if not, let me know and i'll be glad to change the answer however necessary.

Ohgodwhy
  • 49,779
  • 11
  • 80
  • 110
  • +1 This would work if I knew all of the animations up front. My issue is the animations are tacked on from keyboard events so I can't possibly know the chain of animations up front. – anthony sottile Jun 18 '12 at 06:09
  • Fair enough. Could you show me any working examples on the web so I can better tailor my answer to your specific issue? – Ohgodwhy Jun 18 '12 at 14:18
1

If I understand correctly then you are worrying unnecessarily. The behaviour you want is the natural jQuery animation behaviour in which each element has its own queue, and there's no particular reason not to use the default "fx" queue unless some other aspect of the application requires it.

DEMO

You will see in the demo that the positions of a red and green block can be independently controlled and their movement independently stopped.

Most of the code exists to achieve the nice layout. The operative bits are the animations object literal (a bunch of named css maps) and the anonymous click handler attached to the edge controls (which invokes the appropriate css map to cause the selected block to move to the demanded position).

The only thing you might want to do differently is to handle non-numeric animations (eg. class switching). jQuery's .animate() only handles the animation of numeric css values but the good news is that non-numeric stuff can be handled without too much difficulty if required (see .queue() and .dequeue()).

Beetroot-Beetroot
  • 18,022
  • 3
  • 37
  • 44
  • Correct, each queue is stored on the element's data. Also, nice demo! :) – Mattias Buelens Jun 19 '12 at 12:21
  • Yeah I guess that does work... Why does jQuery have named queues then? – anthony sottile Jun 20 '12 at 03:20
  • 1
    Named queues allow you to define and manage separate sequences of actions for a single element, each queue running asynchronously with respect to all other queues. For example, you may have one queue that controls an element's x-movement and another that controls its y-movement. The separate queues would allow you to stop x-movement without stopping y-movement (don't ask me why you might want to do this - it's a contrived example). – Beetroot-Beetroot Jun 20 '12 at 10:51