2012-11-24 70 views
1

我正在創建一個實用程序方法,它有助於依次使用jQuery淡化元素。正如你在下面的代碼中看到的,我將添加一個額外的類作爲alreadyFadedIn一個標誌。在方法調用sequentiallyFadeIn(...)結束時,我想執行cleanUp,我想要刪除在sequentiallyFadeIn(...)方法中所選元素中添加的標誌類。如何強制javascript函數同步/順序執行?

<html> 
<head> 
<script src="http://code.jquery.com/jquery-latest.js"></script> 
<script type="text/javascript"> 
$(document).ready(function() { 

    function sequentialFadeIn(selectorText, speed, display, callBack) { 

     display = typeof display !== 'undefined' ? display : "block"; 

     function helper() { 
      nextElementToFadeIn = $(selectorText).not(".alreadyFadedIn").first(); 
      nextElementToFadeIn.fadeIn(speed, function() { 
       $(this).addClass("alreadyFadedIn"); 
       helper(); 
      }).css("display", display); 
     } 
     helper(); 

     callBack(selectorText);  
    } 
    sequentialFadeIn(".toBeFaddedIn", "slow", "inline-block",function cleanUp(selectorText1){ 
      $(selectorText1).removeClass("alreadyFadedIn"); 
      console.log("Clean up has been performed."); 
        console.log("Selector Text: " +selectorText1); 

     }); 

}); 

</script> 

</head> 
<body><style media="screen" type="text/css"> 
.hello { 
    background-color: blue; 
    height:50px; 
    width: 50px; 
    display: none; 

} 
</style> 

<div class="hello toBeFaddedIn"></div> 
<div class="hello toBeFaddedIn"></div> 
<div class="hello toBeFaddedIn"></div> 
<div class="hello toBeFaddedIn"></div> 
<div class="hello toBeFaddedIn"></div> 

</body></html> 

雖然看着檢查元素,我注意到類alreadyFadedIn沒有被刪除。原因在我看來,cleanUp方法是異步執行的,它與helper()sequentiallyFadeIn方法的主邏輯一起被異步執行。您還可以注意到日誌消息「已執行清理」。甚至在div完成淡入之前即可打印。

如何使cleanUp調用在sequentiallyFadedIn方法中的主邏輯完成後執行?有什麼建議麼?上的jsfiddle

代碼:http://jsfiddle.net/BztLx/11/

+1

一旦'nextElementToFadeIn'不再包含任何元素,看起來你必須在'helper'函數內運行回調。 –

+0

您需要在'fadeIn'的完成函數中調用'callBack'函數。 – Barmar

+0

你的代碼立即執行'helper'(它會移除類'alreadyFadedIn'),並且當fadeIn動畫完成時,執行添加類'alreadyFadedIn'的匿名函數。這似乎是錯誤的。但你有那裏的成分來修復邏輯。您可以立即或在動畫結束時執行代碼。 –

回答

4

你需要檢查的任何元素是否留在被褪色如果沒有元素仍然存在,調用清理回調。下面是我如何實現它:

if ($(selectorText).is(":not(.alreadyFadedIn)")) { 

     //Your main logic 
     nextElementToFadeIn = $(selectorText).not(".alreadyFadedIn").first(); 
     nextElementToFadeIn.fadeIn(speed, function() { 
      $(this).addClass("alreadyFadedIn"); 
      helper(); 
     }).css("display", display); 

    } else { 

     //No elements remain, cleanup time 
     callBack(selectorText); 
    } 

在外部條件我檢查是否至少有一個元素不淡入,否則我調用回調。

示範:http://jsfiddle.net/BztLx/12/

+0

基於@ FelixKing的建議,我也提出了類似的問題。演示:http://jsfiddle.net/BztLx/14/ – Atharva

3

更方便,更清潔,更快,如果你只是重寫你的代碼是這樣的......

$(document).ready(function() { 

    function sequentialFadeIn(selectorText, speed, display, callBack) { 

     display = display || "block"; 

     var els = $(selectorText), 
       i = 0; 

     (function helper() { 
      els.eq(i++).fadeIn(speed, helper).css("display", display); 
      if (callback && i === els.length) 
       callback(selectorText); // Not really needed any more 
     })(); 
    } 

    sequentialFadeIn(".toBeFaddedIn", "slow", "inline-block", function cleanUp(selectorText1){ 
     // not really needed any more 
     // $(selectorText1).removeClass("alreadyFadedIn"); 
    }); 
}); 

DEMO:http://jsfiddle.net/BztLx/15/

你正在做的方式更多的DOM選擇比需要。

+1

啊!美麗:)當我們有'.eq()'作爲循環時,誰需要額外的標誌!感謝您指出這種方式。 – Atharva

+0

不客氣。 –

+0

對於eq(i ++)技巧+1 + – Christophe

2

要在我的評論擴大,這裏是不使用額外類的簡化版本:

function fadeThenNext(element){ 
    element.fadeIn("fast", function() { 
     element=element.next(".toBeFaddedIn"); 
     if (element.length) fadeThenNext(element); 
    }); 
} 
fadeThenNext($(".toBeFaddedIn").first()); 

演示:http://jsfiddle.net/BztLx/17/

[更新]更寬泛的版本,如果要素沒有兄弟姐妹:

function fadeSequence(elements){ 
    elements.first().fadeIn("fast", function() { 
     fadeSequence(elements.slice(1)); 
    }); 
} 
fadeSequence($(".toBeFaddedIn")); 

小提琴:http://jsfiddle.net/BztLx/22/

+0

它需要選擇的元素是彼此的兄弟姐妹,有時可能並非如此。但適用於需要應用這種效果的一些場景,可以在元素列表中進行說明。 – Atharva

+0

沒錯,對於一個更通用的代碼,你需要在@ user1689607的示例中迭代選擇器。關鍵是你不需要額外的課程! – Christophe

+1

@Atharva看到我的更新爲更通用的版本。 – Christophe