2012-07-10 70 views
2

我試圖創建這種滑動效果,但我遇到的唯一問題是排隊。jQuery中的通用動畫隊列?

$(this).animate({'left' : '0%'}, randTime, function() { 
    $(this).animate({'boxShadow' : 'none'}); 
    setTimeout(function() { 
     $container.children('.slice').addClass('noshadow'); 
     $('body > div:not(#'+container+') .slice').each(function() { 
      restartAnimation($(this)); 
     });    
    $container.children('.content').fadeIn(); 
    }, (aLength+100)); 
}); 

上面的容器變量是當前容器。我做了:沒有(容器),所以當前的容器將繼續動畫。這全部在一個包含兩個屬性的函數中,即容器元素的ID和動畫將運行的方式(僅關鍵字貫穿if語句)。然後,我將有激活這樣的動畫菜單:

if($(this).attr('name') == 'home') { 

    animation('home', 'top'); 

} 
else if { ..... 

重啓動畫功能只需重新啓動所有其他的動畫元素到原來的位置,使他們能夠再次運行。現在,問題是,直到重新啓動功能運行纔會有延遲,所以如果在延遲時間內單擊兩個菜單項,最終重新啓動功能運行,然後一切都變得非常困惑。

我需要一種方法將動畫重新啓動回原來的位置,以便它可以再次運行,但不會干擾並重新啓動其他動畫元素。否則,我們會陷入一片混亂。我已經建立了一個快速jsFiddle,所以你可以嘗試一下效果。這段代碼現在有點亂,我計劃在完成後整理一切,但這個排隊問題真的讓我陷入了困境。 http://jsfiddle.net/qe7dj/

+1

1+不錯的效果。 – Eonasdan 2012-07-10 17:46:32

+0

是boxShadow的動畫嗎?或者你想使用.css()? – Bergi 2012-07-10 19:05:04

回答

2

解決此問題的一種方法是在第一個動畫完成之前不允許另一個動畫啓動。

可能有幾種方法可以做到這一點,但想到的是創建一個全局函數隊列對象(我將給出一個解釋和下面的代碼)。

您需要一個全局變量來跟蹤當前有多少幻燈片正在動畫。

var animationsRunning = 0; 

每當幻燈片動畫開始時,增加上述變量。當幻燈片動畫結束時,將其遞減。

現在,在開始整個新動畫(多個幻燈片)之前,請檢查該變量。如果幻燈片正在動畫,請將動畫功能添加到全局函數隊列中。如果沒有,請繼續並像正常一樣運行動畫。

if ($(this).attr('name') == 'home') { 
    if (animationsRunning < 1) { 
     animation('home', 'top'); 
    } 
    else { 
     funqueue.push(wrapFunction(animation, this, ['home', 'top'])); 
    } 
} 
else if ($(this).attr('name') == 'about') { 
    if (animationsRunning < 1) { 
     animation('about', 'left'); 
    } 
    else { 
     funqueue.push(wrapFunction(animation, this, ['about', 'left'])); 
    } 
} 

else if ($(this).attr('name') == 'services') { 
    if (animationsRunning < 1) { 
     animation('services', 'hslide'); 
    } 
    else { 
     funqueue.push(wrapFunction(animation, this, ['services', 'hslide'])); 
    } 
} 

每當所有幻燈片完成動畫,檢查全局函數隊列中是否有任何項目。如果有,執行第一個。

if (animationsRunning < 1 && funqueue.length > 0) { 
    (funqueue.shift())(); 
} 

有關功能隊列中的代碼如下所示:

// Function wrapping code. 
// fn - reference to function. 
// context - what you want "this" to be. 
// params - array of parameters to pass to function. 
var wrapFunction = function(fn, context, params) { 
    return function() { 
     fn.apply(context, params); 
    }; 
}; 

// Global function queue 
var funqueue = []; 

Stack Overflow question here具有全局函數隊列概念的一個很好的解釋,所以我不會詳細解釋一下這裏。

可以找到一個可用的jsfiddle示例here

編輯:

您可能需要防止的等待動畫的堆積 - 如果是這樣的話你根本就加入了最新的項目之前清除功能的隊列。很明顯,在這種情況下你實際上並不需要隊列,但是我已經將它保留下來以便與第一個解決方案兼容。

更新的jsFiddle位於here

+0

這個完美的作品!我嘗試了動畫停止的事情,但我不知道如何工作隊列或任何東西。非常感謝。 – Johnny 2012-07-10 23:29:51