在.each()完成后调用jQuery函数

Lut*_*ker 180 each jquery

在jQuery中,是否可以在调用(或任何其他类型的迭代回调)完成后调用回调触发事件..each()

例如,我想要"淡化和删除"来完成

$(parentSelect).nextAll().fadeOut(200, function() {
    $(this).remove();
});
Run Code Online (Sandbox Code Playgroud)

在做一些计算并在之后插入元素之前$(parentSelect).如果jQuery仍然可以看到现有元素并且睡眠/延迟一些任意时间(每个元素200个)似乎是一个脆弱的解决方案,那么我的计算是不正确的.

我可以很容易地.bind()为事件回调提供必要的逻辑但是我不确定如何.trigger()在上面的迭代完成之后干净地调用它.显然,我不能在迭代中调用触发器,因为它会多次触发.

在这种情况下$.each(),我考虑在数据参数的末尾添加一些东西(我将在迭代体中手动查找),但我不想被迫这样,所以我希望有一些其他的优雅关于迭代回调控制流的方法.

小智 163

可能要迟到但我觉得这段代码工作......

$blocks.each(function(i, elm) {
 $(elm).fadeOut(200, function() {
  $(elm).remove();
 });
}).promise().done( function(){ alert("All was done"); } );
Run Code Online (Sandbox Code Playgroud)

  • 从什么时候开始每个人都返回一个承诺?请检查:api.jquery.com/each (4认同)

Poi*_*nty 159

替代@ tv的答案:

var elems = $(parentSelect).nextAll(), count = elems.length;

elems.each( function(i) {
  $(this).fadeOut(200, function() { 
    $(this).remove(); 
    if (!--count) doMyThing();
  });
});
Run Code Online (Sandbox Code Playgroud)

请注意,.each()它本身是同步的 - 调用.each()之后的语句将仅在.each()调用完成后执行.然而,异步操作开始.each()迭代当然会继续以自己的方式上.这就是问题所在:淡化元素的调用是由定时器驱动的动画,并且这些动画按照自己的节奏继续.

因此,上面的解决方案会跟踪褪色的元素数量.每次调用.fadeOut()都会获得完成回调.当回调注意到它通过所涉及的所有原始元素计数时,可以放心地采取一些后续动作,即所有衰落都已完成.

这是一个有四年历史的答案(2014年的这一点).一种现代的方法可能涉及使用延迟/承诺机制,虽然上面很简单,应该可以正常工作.

  • 我喜欢这个改变,虽然我将比较为0而不是逻辑否定(--count == 0),因为你倒计时了.对我而言,它使意图更清晰,尽管它具有相同的效果. (4认同)

nbs*_*bsp 156

好吧,这可能是事后的一点点,但.promise()也应该实现你所追求的目标.

承诺文件

我正在研究的一个项目的例子:

$( '.panel' )
    .fadeOut( 'slow')
    .promise()
    .done( function() {
        $( '#' + target_panel ).fadeIn( 'slow', function() {});
    });
Run Code Online (Sandbox Code Playgroud)

:)

  • .promise()在.each()上不可用 (3认同)

use*_*716 23

JavaScript同步运行,因此无论你放置什么each()都不会运行,直到each()完成.

考虑以下测试:

var count = 0;
var array = [];

// populate an array with 1,000,000 entries
for(var i = 0; i < 1000000; i++) {
    array.push(i);
}

// use each to iterate over the array, incrementing count each time
$.each(array, function() {
    count++
});

// the alert won't get called until the 'each' is done
//      as evidenced by the value of count
alert(count);
Run Code Online (Sandbox Code Playgroud)

调用警报时,count将等于1000000,因为警报each()在完成之前不会运行.

  • 给出的示例中的问题是fadeOut被置于动画队列中并且不会同步执行.如果你使用`each`并分别安排每个动画,你仍然需要在动画之后激活事件,而不是每个动画结束. (8认同)
  • @tvanfosson - 是的,我知道.根据Luther想要完成的事情,你的解决方案(和Pointy的)似乎是正确的方法.但是从路德的评论中可以看出......**天真,我正在寻找类似elems.each(foo,bar)的东西,其中foo ='函数应用于每个元素',bar ='回调完成所有迭代后'.**......他似乎坚持认为这是一个"每个()"问题.这就是为什么我把这个答案混合在一起. (3认同)

Jim*_*imP 5

我发现很多响应处理数组而不是json对象.我的解决方案只是在递增计数器时迭代对象一次,然后在迭代对象以执行代码时,您可以递增第二个计数器.然后,您只需将两个计数器进行比较并获得解决方案.我知道它有点笨重,但到目前为止我还没有找到更优雅的解决方案.这是我的示例代码:

var flag1 = flag2 = 0;

$.each( object, function ( i, v ) { flag1++; });

$.each( object, function ( ky, val ) {

     /*
        Your code here
     */
     flag2++;
});

if(flag1 === flag2) {
   your function to call at the end of the iteration
}
Run Code Online (Sandbox Code Playgroud)

就像我说的那样,它不是最优雅的,但是它有效并且运行良好,我还没有找到更好的解决方案.

干杯,JP


Sof*_*ixt 5

我正在使用这样的东西:

$.when(
           $.each(yourArray, function (key, value) {
                // Do Something in loop here
            })
          ).then(function () {
               // After loop ends.
          });
Run Code Online (Sandbox Code Playgroud)