开发者

A non-nested animation sequence in jQuery?

开发者 https://www.devze.com 2023-03-23 03:25 出处:网络
I\'m trying to create an animation sequence with jQuery where one animation starts after the previous one is done. But I just can\'t wrap my head around it. I\'ve tried to make use of the jQuery.queue

I'm trying to create an animation sequence with jQuery where one animation starts after the previous one is done. But I just can't wrap my head around it. I've tried to make use of the jQuery.queue, but I don't think I can use that because it seems to have one individual queue for each element in the jQuery array.

I need something like:

$('li.some').each(function(){
    // Add to queue
    $(this).an开发者_Go百科imate({ width: '+=100' }, 'fast', function(){
        // Remove from queue
        // Start next animation
    });
});

Is there a jQuery way to do this or do I have to write and handle my own queue manually?


You can make a custom .queue() to avoid the limitless nesting..

var q = $({});

function animToQueue(theQueue, selector, animationprops) {
    theQueue.queue(function(next) {
        $(selector).animate(animationprops, next);
    });
}

// usage
animToQueue(q, '#first', {width: '+=100'});
animToQueue(q, '#second', {height: '+=100'});
animToQueue(q, '#second', {width: '-=50'});
animToQueue(q, '#first', {height: '-=50'});

Demo at http://jsfiddle.net/gaby/qDbRm/2/


If, on the other hand, you want to perform the same animation for a multitude of elements one after the other then you can use their index to .delay() each element's animation for the duration of all the previous ones..

$('li.some').each(function(idx){
    var duration = 500; 
    $(this).delay(duration*idx).animate({ width: '+=100' }, duration);
});

Demo at http://jsfiddle.net/gaby/qDbRm/3/


The callback of .animate() actually accepts another .animate(), so all you would have to do would be

    $(this).animate({ width: '+=100' }, 'fast', function(){
         $(selector).animate({attr: val}, 'speed', function(){
});
    });

and so on.


You could call the next one recursively.

function animate(item) {
    var elem = $('li.some').eq(item);
    if(elem.length) {
        elem.animate({ width: '+=100' }, 'fast', function() {
            animate(item + 1);
        });
    }
}

animate(0);


why not build up a queue?

var interval = 0; //time for each animation
var speed = 200;

$('li.some').each(function(){
    interval++;
    $(this).delay(interval * speed).animate({ width: '+=100' }, speed);
});

EDIT: added speed param


Thanks to everybody replying!

I thought I should share the outcome of my question. Here is a simple jQuery slideDownAll plugin that slides down one item at a time rather than all at once.

(function ($) {

    'use strict';

    $.fn.slideDownAll = function (duration, callback) {

        var that = this, size = this.length, animationQueue = $({});

        var addToAnimationQueue = function (element, duration, easing, callback) {
            animationQueue.queue(function (next) {
                $(element).slideDown(duration, easing, function () {
                    if (typeof callback === 'function') {
                        callback.call(this);
                    }
                    next();
                });
            });
        };

        return this.each(function (index) {
            var complete = null,
                easing = 'linear';
            if (index + 1 === size) {
                complete = callback;
                easing = 'swing';
            }
            addToAnimationQueue(this, duration / size, easing, complete);
        });
    };

} (jQuery));

Not very well test, but anyways.

Enjoy!!

0

精彩评论

暂无评论...
验证码 换一张
取 消