【问题标题】:How to write a loop in jQuery which waits for each function to complete before continuing the loop如何在jQuery中编写一个循环,在继续循环之前等待每个函数完成
【发布时间】:2023-04-05 20:27:01
【问题描述】:

如果这是显而易见的,请原谅我。

我的页面上有未知数量的元素,我需要一次遍历一个元素并对其进行处理。但是,我需要暂停循环,直到元素上使用的函数完成,然后继续进行下一次迭代。

我尝试在 $.each 循环中执行此操作,但它会快速触发命令并完成,而无需等待它们完成。

有什么想法吗?

$('elem').each(function(){
    $(this).fadeIn().wait(5000).fadeOut();
});

这就是我所拥有的,非常简单。 我从这里得到了 wait() 函数:jquery cookbook site

问题是,循环等待 - 实际的命令按预期工作,只是它们都立即关闭。

任何帮助表示赞赏,谢谢。

编辑:执行此操作后,我可能想再次执行循环,以便元素列表将再次按顺序淡入/淡出

EDIT2:已经获得了 1.4.2 jQuery 库,使用的是 1.3.2,因此使用了自定义 wait() 函数。现在使用 lobstrosity 提到的 delay() 。 设法从他的回答中拼凑出一些接近我需要的东西,谢谢 lobstrosity :)。

【问题讨论】:

    标签: jquery loops wait each synchronous


    【解决方案1】:

    首先,jQuery 1.4 添加了delay 函数,我认为这是您的自定义等待实现正在做的事情。

    使用延迟,您可以通过使用每个回调的第一个参数作为初始延迟的乘数来假装每个元素“等待”前一个元素完成的功能。像这样:

    var duration = 5000;
    
    $('elem').each(function(n) {
        $(this).delay(n * duration).fadeIn().delay(duration).fadeOut();
    });
    

    所以第一个元素会立即淡入。第二个将在 5,000 毫秒后淡入。 10,000 毫秒后的第三个,依此类推。请记住,这是伪造的。每个元素实际上并没有等待前一个元素完成。

    【讨论】:

    • aaaahh 这很接近,谢谢。我使用的是 1.3.2,刚刚获得了最新的库,感谢您指出这一点。这个唯一的问题是,一旦我对 $('.elem') 执行操作,我可能想再做一次。我将编辑问题以反映这一点,应该提到它,谢谢。
    • 我还没有做到完美,但这回答了我的问题,非常感谢。
    【解决方案2】:

    您使用each() 的主循环将在您的元素集合上运行而不会延迟。您需要将这些元素排队。

    这可能需要调整(并且可能使用 jQuery 队列?),但要演示使用递归来处理队列:

    function animate(elems) {
        var elem = elems.shift();
        $(elem).fadeIn().wait(5000).fadeOut(2000, function() {
            if (elems.length) {
                animate(elems);
            }
        });
    }
    
    var elems = $('elem');
    animate(elems);
    

    【讨论】:

    • 我认为未知数量的元素对此很好,因为我们只是 shift() 数组中的下一个元素。这只会在您的集合上运行一次,然后终止。
    • shift 似乎不适用于 jquery 对象,我收到此错误:TypeError: 'undefined' is not a function (evaluating 'elems.shift()')
    • 刚刚建立的解决方案:使用 get() : var elems = $("elem").get();
    【解决方案3】:

    您可能需要在第一个函数之前调用 wait :

      $(this).wait().fadeIn().wait(5000).fadeOut();
    

    另一种选择是使用回调。

     $(this).wait().fadeIn('slow', function(){$(this).fadeOut('slow')});
    

    这样,在fadeIn 完成之前,fadeOut 不会开始。

    【讨论】:

    • 感谢您的回答,但fadeIn 和fadeOuts 的顺序不是问题,事实是.each 循环在大约0.3 秒内调用它们中的每一个,并使它都是同时发生的,我需要循环等待回调。
    【解决方案4】:

    这是我的solution 的演示。

    您需要的不是处理处理的循环。你想要的是链接调用。似乎可能有一种更简单的方法,但这是一种蛮力方法。

    // Create a function that does the chaining.
    function fadeNext(x,y) {
      return function() { x.fadeIn(100).delay(100).fadeOut(1000, (y?y.fadeNext:y)); };
    }
    
    // Get all the elements to fade in reverse order.
    var elements = [];
    $('.f').each(function(i,e) {elements.unshift(e);});
    
    // Iterate over the elements and configure a fadeNext for each.
    var next;
    for (var i in elements) {
      var e = $(elements[i]);
      e.fadeNext = fadeNext(e,next);
      next = e;
    }
    
    // Start the fade.
    next.fadeNext();
    

    【讨论】:

    • 这是个好主意,谢谢发帖。这段代码很好:)
    猜你喜欢
    • 2015-11-30
    • 1970-01-01
    • 2021-11-26
    • 2021-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-25
    • 1970-01-01
    相关资源
    最近更新 更多