2012-11-24 72 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