Search code examples
jqueryanimationchaining

jQuery chained animation without plugin


Before with jQuery I could do a chained animation with a delay between like so:

$("#element").delay(45).animate({ }, 45)
             .delay(45).animate({ }, 45)
             .delay(45).animate({ }, 45);

Now since the update to v1.6.1 instead of doing what it did previously, it now skips to the last animation. Ignoring the previous statements. I know I can do an oncomplete callback for each animation but that just get's messy:

$("#element").delay(45).animate({ }, 45, function(){
    $("#element").delay(45).animate({ }, 45, function(){
        $("#element").delay(45).animate({ }, 45);
    })
}) 

Does anyone know how I can accomplish this in a simple clean way?


Solution

  • Here is the second way as requested. I post it in another answer, because it is more complex, and perhaps less beautiful. To play with it see: http://jsfiddle.net/LMptt/1/

    Usage: use a string with + or - to indicate a relative timestamp. The order matters for relative timestamps (relative to the previous action that is). Use "+0" or '-0' for the same timestamp as the previous one. Absolute timestamps (integers) can be put anywhere in the list.

    $(document).ready(function ()
    {
        queue([
            [2000, function () {  $('.two').slideUp(); }],
            ['-1000', function () {  $('.one').slideUp(); }],
            [3000, function () {  $('.three').slideUp(); }],
            ['+1000', function () {  $('.four').slideUp(); }]
        ]);
    
    });
    
    /**
     * Queue.js
     *
     * @author Arend van Waart
     *
     *  This will allow for events to be queued by (relative) timestamp
     */
    
     function queue (queue){
        var self = this;
        // queue
        this.queue = queue;
        // time passed is 0
        this.timePassed = 0;
        // time in ms to sleep between checks.
        this.sleep = 100;
    
        var time = new Date();
        this.lastTime = time.getTime();
        this.iterate = function(){
            var total = 0;
            var time = new Date();
    
            // how much time has passed since we slept?
            self.timePassed = self.timePassed + (time.getTime() - self.lastTime);
            self.lastTime = time.getTime();
    
            for (var i in self.queue) {
                if (self.queue[i][0] <= self.timePassed){
                    self.queue[i][1]();
                    self.queue.splice(i,1);
                } else {
                    // added sorting now, so we don't have to evaluate the rest.
                    break;
                }
            }
    
            if (self.queue.length == 0){
                return;
            }else{
                setTimeout(self.iterate, self.sleep);
            }
        }
    
    
        this.parseRelative = function ()
        {
            var absoluteQueue = [];
            var lastAbsolute = 0;
            for (var i in queue)
            {
               var absolute;
               var firstChar = String(queue[i][0]).charAt(0);
               if (firstChar == "+" ||  firstChar == "-")
               {
                  absolute = lastAbsolute + parseInt(queue[i][0]);
               } else {
                  absolute = parseInt(queue[i][0]);
               }
               lastAbsolute = absolute;
               absoluteQueue.push([absolute, queue[i][1]]);
            }
            this.queue = absoluteQueue;
        }
        this.sort = function (a,b)
        {
            return a[0] - b[0];
        }
    
        this.parseRelative();
        this.queue.sort(this.sort);
        this.iterate();
    }