2011-07-26 50 views
6

我試圖用jQuery創建一個動畫序列,其中一個動畫在前一個動畫完成後啓動。但我無法把頭圍住它。我試圖使用jQuery.queue,但我不認爲我可以使用它,因爲它似乎有一個單獨的隊列中的每個元素在jQuery數組中。jQuery中的非嵌套動畫序列?

我需要這樣的東西:

$('li.some').each(function(){ 
    // Add to queue 
    $(this).animate({ width: '+=100' }, 'fast', function(){ 
     // Remove from queue 
     // Start next animation 
    }); 
}); 

是否有一個jQuery辦法做到這一點還是我寫的和手動處理我自己的隊列?

回答

16

您可以自定義.queue()避免無限嵌套..

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'}); 

演示在http://jsfiddle.net/gaby/qDbRm/2/


如果,另一方面,您希望爲多個元素執行相同的動畫Ë後對方,那麼你可以使用它們的索引來.delay()每個元素的動畫了之前所有的持續時間..

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

演示在http://jsfiddle.net/gaby/qDbRm/3/

+0

完美!謝謝! – 98374598347934875

2

.animate的回調()實際上接受另一.animate(),所以你必須做的是

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

等。

+0

+1這是鏈接動畫的標準方式。很簡單。 – maxedison

+1

但是你不能在循環中做到這一點。注意'每個'! – 98374598347934875

1

您可以遞歸調用下一個。

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

animate(0); 
+1

這個也可以。謝謝! – 98374598347934875

1

爲什麼不建立隊列?

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

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

編輯:加入了倍速PARAM

+0

這樣可靠嗎?你確定第一個動畫會在那時完成嗎? – 98374598347934875

+0

是的,現在它的可靠。已添加速度參數 – Tarun

1

感謝大家回覆!

我以爲我應該分享我的問題的結果。以下是一個簡單的jQuery slideDownAll插件,可以一次滑下一個項目,而不是一次滑動一個項目。

(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)); 

不是很好的測試,但無論如何。

享受!