5

我试图从循环中调用一个函数,当函数完成执行时,循环继续到下一次迭代并再次调用它。但是循环不会等待函数完成,而是调用函数的 4 个实例并同时运行它们!我应该把整个函数放在循环中还是让循环等待函数执行?谢谢

    for (var i=2; i<=4; i++){
        galleryAnimation(i); //This is executed 3 times at once
    }
    function galleryAnimation(i){
        $("#pic" + i).delay(delayTime).fadeIn(duration);
    }       
4

4 回答 4

3

就像您要求的那样,该函数正在执行 3 次,问题是 delay 和 fadeIn 都使用计时器:它们在将来执行该函数并立即返回时设置了一个计时器:它们是非阻塞调用。因此,在您的情况下,因为您在 0.0001s、0.0002s 和 0.0003s 处调用该函数 3 次,所以这三个在 5.0001、5.0002 和 5.0003 处开始。

您想到的是阻止对这些函数的调用。您希望整个执行停止,直到动画完成。这将在此期间停止整个浏览器 Javascript 引擎,这意味着无法进行其他动画或用户 javascript 交互。

要解决它,您必须使用回调。您可以向fadeIn 提供一个函数,该函数将在动画完成后调用:

http://api.jquery.com/fadeIn/

您可以使用队列在 delay() 上进行相同的模拟:

回调 .delay()

于 2013-08-19T10:58:09.380 回答
1

简单的解决方案:每次将超时时间增加一个因子。

var i, factor, 
    duration = 250,
    delayTime = 500;

for (i = 2, factor = 0; i <= 4; i++, factor++) {
    galleryAnimation(i, factor);
}

function galleryAnimation(i, factor) {
    $("#pic" + i).delay(factor * delayTime).fadeIn(duration);
}

这与您的方法运行方式相同,只是每次延迟都会变长。

通用解决方案 1 - 使用以预定义的时间间隔调用setInterval()您的工作函数(执行的那个):fadeIn

var elements = $("#pic2,#pic3,#pic4").toArray(),   // or any other way to select your elements
    duration = 250,
    delayTime = 500,
    intervalId = setInterval(function () {
        $(elements.shift()).fadeIn(duration);
        if (elements.length === 0) {
            clearInterval(intervalId);
        }
    }, delayTime);

通用解决方案 2 - 使用在前一个动画完成时调用的回调:

var elements = $("#pic2,#pic3,#pic4").toArray(),   // or any other way to select your elements
    duration = 250,
    delayTime = 500,
    next = function () {
        $(elements.shift()).delay(delayTime).fadeIn(duration, next);
    };

next();  // start the chain
于 2013-08-19T11:41:43.600 回答
0

您可以做的一件事是使用标识符(布尔值),然后在循环中测试标识符以确定循环是否可以继续或停止。例如, function galleryAnimation(i, iBool){ $("#pic" + i).delay(delayTime).fadeIn(duration);
iBool = 0; }

然后在返回时;

for (var i=2; i<=4; i++){
    galleryAnimation(i, iBool); 
    // If iBool = 0 then continue
    // Else Break
}

这可能是一个解决方案,因为循环需要返回值来确定下一步,继续或中断。

于 2013-08-19T11:00:48.170 回答
0

我提供了我自己的解决方案,它似乎工作得很好,这是我的代码:

function fadeInAnimation(index){
        $("#pic" + index).delay(delayTime).fadeIn(duration, function(){
            photoIndex();
        });
    }

    function photoIndex(){
        index++;
        fadeInAnimation(index);
    }
    fadeInAnimation(index);
});

我已经意识到在这样的事情上使用循环是一个非常糟糕的主意。此代码将允许我添加任意数量的图像,只需在文件夹中重命名它们,而不是手动将它们编码为每张照片的回调。感谢那些回答的人。您的建议很棒,并且一定会在像这样的其他应用程序中记住它们

于 2013-08-19T13:34:49.777 回答