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

在jQuery中,是否有可能在调用 .each() (或任何其他types的迭代callback) 完成后调用callback触发事件

例如,我想这个“淡入淡出”来完成

 $(parentSelect).nextAll().fadeOut(200, function() { $(this).remove(); }); 

在做一些计算并在$(parentSelect)之后插入新的元素之前。 我的计算是不正确的,如果现有的元素仍然是可见的jQuery和睡眠/延迟一些任意时间(每个元素200)似乎是一个脆弱的解决scheme充其量。

我可以很容易.bind()必要的逻辑到一个事件callback,但我不知道如何干净地调用.trigger()上面的迭代完成后 。 显然,我不能在迭代中调用触发器,因为它会多次触发。

$.each()的情况下,我已经考虑在数据参数的末尾添加一些东西(我会在迭代体中手动查找),但是我讨厌被迫这样做,所以我希望有一些其他优雅的方式来控制迭代callback的stream程。

@电视的答案替代:

 var elems = $(parentSelect).nextAll(), count = elems.length; elems.each( function(i) { $(this).fadeOut(200, function() { $(this).remove(); if (!--count) doMyThing(); }); }); 

请注意.each()本身是同步的 – 调用.each()之后的.each()只有在.each()调用完成后才会执行。 然而,在.each()迭代中开始的asynchronous操作当然会以自己的方式继续进行。 这就是问题所在:淡化元素的调用是由定时器驱动的animation,而且这些animation以自己的速度继续。

因此,上面的解决scheme会跟踪有多less元素正在褪色。 每次调用.fadeOut()都会得到一个完成callback。 当callback注意到通过所有涉及的原始元素进行计数时,可以有把握地确信所有的衰落都已经完成。

这是一个四岁的答案(在这一点上在2014年)。 一个现代化的方式可能会涉及使用延迟/承诺机制,虽然上面是简单的,应该工作得很好。

好的,这可能是事实之后的一小部分,但是.promise()也应该可以实现。

承诺文件

我正在从事一个项目的一个例子:

 $( '.panel' ) .fadeOut( 'slow') .promise() .done( function() { $( '#' + target_panel ).fadeIn( 'slow', function() {}); }); 

🙂

这可能是晚了,但我认为这个代码工作…

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

JavaScript同步运行,所以无论你在each()之后放置什么,在each()完成之前each()不会运行。

考虑以下testing:

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

当警报被调用时,count将等于1000000,因为直到each()完成后警报才会运行。

我发现了很多处理数组的响应,但没有使用json对象。 我的解决scheme是简单地遍历对象一次递增计数器,然后迭代通过对象执行您的代码时,您可以增加第二个计数器。 然后,您只需将两个计数器进行比较并获得您的解决scheme。 我知道这有点笨重,但我还没有find一个更优雅的解决scheme。 这是我的示例代码:

 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 } 

就像我说的那样,这不是最优雅的,但它的工作原理,它运作良好,我还没有find一个更好的解决scheme。

干杯,JP

如果你愿意做几个步骤,这可能工作。 虽然这取决于animation的整理顺序。 我不认为这应该是一个问题。

 var elems = $(parentSelect).nextAll(); var lastID = elems.length - 1; elems.each( function(i) { $(this).fadeOut(200, function() { $(this).remove(); if (i == lastID) { doMyThing(); } }); }); 

关于什么

 $(parentSelect).nextAll().fadeOut(200, function() { $(this).remove(); }).one(function(){ myfunction(); }); 

你必须排队请求的其余部分才能正常工作。

 var elems = $(parentSelect).nextAll(); var lastID = elems.length - 1; elems.each( function(i) { $(this).fadeOut(200, function() { $(this).remove(); if (i == lastID) { $j(this).queue("fx",function(){ doMyThing;}); } }); }); 

我遇到同样的问题,我解决了像下面的代码的解决scheme:

 var drfs = new Array(); var external = $.Deferred(); drfs.push(external.promise()); $('itemSelector').each( function() { //initialize the context for each cycle var t = this; // optional var internal = $.Deferred(); // after the previous deferred operation has been resolved drfs.pop().then( function() { // do stuff of the cycle, optionally using t as this var result; //boolean set by the stuff if ( result ) { internal.resolve(); } else { internal.reject(); } } drfs.push(internal.promise()); }); external.resolve("done"); $.when(drfs).then( function() { // after all each are resolved }); 

该解决scheme解决了以下问题:使用Deferred对象同步在.each()迭代中启动的asynchronous操作。