如何强制javascript函数同步/顺序执行?

如何强制javascript函数同步/顺序执行?,javascript,jquery,html,asynchronous,Javascript,Jquery,Html,Asynchronous,我正在创建一个实用方法,它可以帮助使用jQuery按顺序淡入元素。正如您在下面的代码中所看到的,我添加了一个额外的类作为alreadyFadedIna标志。在方法调用SequentialyFadein(…)结束时,我想执行cleanUp,其中我想删除在SequentialyFadein(…)方法内所选元素中添加的标志类 <html> <head> <script src="http://code.jquery.com/jquery-latest.js"><

我正在创建一个实用方法,它可以帮助使用jQuery按顺序淡入元素。正如您在下面的代码中所看到的,我添加了一个额外的类作为
alreadyFadedIn
a标志。在方法调用
SequentialyFadein(…)
结束时,我想执行
cleanUp
,其中我想删除在
SequentialyFadein(…)
方法内所选元素中添加的标志类

<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>

$(文档).ready(函数(){
功能顺序FADEIN(选择文本、速度、显示、回调){
显示=显示类型!=“未定义”?显示:“块”;
函数助手(){
nextElementToFadeIn=$(selectorText).not(“.alreadyFadeIn”).first();
nextElementToFadeIn.fadeIn(速度,函数(){
$(this.addClass(“alreadyFadedIn”);
助手();
}).css(“显示”,显示);
}
助手();
回调(selectorText);
}
顺序FADEIN(“.toBeFaddedIn”、“慢速”、“内联块”、函数清理(selectorText1){
$(selectorText1.removeClass(“alreadyFadedIn”);
日志(“已执行清理”);
日志(“选择器文本:+selectorText1”);
} );
});
.你好{
背景颜色:蓝色;
高度:50px;
宽度:50px;
显示:无;
}
查看inspect元素时,我注意到类
alreadyFadedIn
没有被删除。在我看来,原因是cleanUp方法与
sequentiallyFadeIn
方法的主逻辑异步执行,该方法位于
helper()
中。您还可以注意到日志消息“cleanup has performed.”甚至在div完成淡入之前就打印出来了

sequentialyfadedin
方法中的主逻辑完成后,如何执行
cleanUp
调用?有什么建议吗


jsiddle上的代码:

您需要检查是否有任何元素仍然需要淡入。如果没有元素保留,则调用清理回调。下面是我如何实现它的:

    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);
    }
在外部条件中,我检查是否至少有一个元素没有淡入,否则调用回调


演示:

您需要检查是否还有任何元素需要淡入。如果没有元素保留,则调用清理回调。下面是我如何实现它的:

    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);
    }
在外部条件中,我检查是否至少有一个元素没有淡入,否则调用回调


演示:

如果您只需像这样重写代码,就更容易、更干净、更快了

$(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");
    });
});

演示:


您所做的DOM选择比需要的多得多。

如果您只需像这样重写代码,就会更容易、更干净、更快

$(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");
    });
});

演示:


您所做的DOM选择远远超出了需要。

要扩展我的评论,这里有一个简化版本,不使用其他类:

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

[更新]如果元素不是兄弟元素,则为更通用的版本:

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

​fiddle:

要扩展我的评论,这里有一个简化版本,不使用其他类:

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

[更新]如果元素不是兄弟元素,则为更通用的版本:

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

​fiddle:

看起来您必须在
helper
函数中运行回调,一旦
nextElementToFadeIn
不再包含任何元素。您需要在
fadeIn
的完成函数中调用
回调
函数。您的代码执行
helper
(这将删除类
alreadyFadedIn
)立即,添加类
alreadyFadedIn
的匿名函数将在fadeIn动画完成后执行。这似乎是错误的。但您有修复逻辑的成分。您可以立即或在动画结束时执行代码。这看起来过于复杂。为什么不使用next()进行链淡入,而无需添加类?@FelixKling您的解决方案成功了!:)以下是JSFIDLE上更新的代码:看起来您必须在
helper
函数中运行回调,直到
nextElementToFadeIn
不再包含任何元素。您需要在
fadeIn
的完成函数中调用
callback
函数。您的代码执行
helper
(这将删除类
alreadyFadedIn
)立即,添加类
alreadyFadedIn
的匿名函数将在fadeIn动画完成后执行。这似乎是错误的。但您有修复逻辑的成分。您可以立即或在动画结束时执行代码。这看起来过于复杂。为什么不使用next()进行链淡入,而不需要添加类?@FelixKling您的解决方案成功了!:)以下是关于jsfiddle的更新代码:我还根据@FelixKing在问题注释中的建议提出了类似的建议。演示:我还根据@FelixKing在问题评论中的建议提出了类似的建议。演示:啊!漂亮:)当我们有
.eq()
作为活套时,谁需要额外的标志呢!谢谢你指出这条路。啊!漂亮:)当我们有
.eq()
作为活套时,谁需要额外的标志呢!感谢您指出这种方式。它要求所选元素彼此是兄弟元素,有时可能并非如此。但适用于某些需要应用此效果的场景,比如在元素列表上。对,对于更通用的代码,您需要遍历选择器,如@user1689607的示例所示。关键是你不需要额外的课程!它要求所选元素彼此是兄弟元素,有时可能并非如此。