How to write a loop in jQuery which waits for each function to complete before continuing the loop

余生长醉 提交于 2019-12-19 05:18:08

问题


Please forgive me if this is an obvious one.

I have an unknown amount of elements on a page, which I need to loop through one at a time and do stuff to. However, I need the loop to pause until the functions used on the elements have completed, and then continue on to the next iteration.

I tried doing this in a $.each loop, but it fired off the commands far to quickly and finished without waiting for them to complete.

Any ideas?

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

This is what I have, very simple. I got the wait() function from here: jquery cookbook site.

Problem is, the loop doesnt wait - the actual command works as intended, it's just that they all go off at once.

Any help appreciated, thanks.

EDIT: After this is executed, I may want to then execute the loop again, so that the list of elems will be faded in / out again in sequence

EDIT2: Have since gotten the 1.4.2 jQuery lib, was using 1.3.2, hence the custom wait() function. Now using delay() as mentioned by lobstrosity. Managed to cobble together something close to what I need from his answer, thanks lobstrosity :) .


回答1:


First of all, jQuery 1.4 added the delay function, which I assume is what your custom wait implementation is doing.

Using delay, you can sort of fake the functionality of each element "waiting" on the previous element to finish by using the first parameter to the each callback as a multiplier for an intial delay. Like this:

var duration = 5000;

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

So the first element will fadeIn immediately. The second will fadeIn after 5,000 ms. The third after 10,000 ms and so on. Keep in mind that this is faking it. Each element is not actually waiting on the previous element to finish.




回答2:


Your main loop using each() will run without delay over your collection of elements. You need to queue these elements instead.

This might need tweaking (and could possibly use jQuery queues?) but to demonstrate using recursion to process the queue:

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

var elems = $('elem');
animate(elems);



回答3:


You probably need to call wait before the first function :

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

The other option is to use the callback.

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

This way the fadeOut does not start until the fadeIn is done.




回答4:


Here's a demo of my solution.

What you need isn't a loop to handle the processing. What you want is to chain the calls. Seems like there might be a simpler way but here's a brute-force method.

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


来源:https://stackoverflow.com/questions/2372301/how-to-write-a-loop-in-jquery-which-waits-for-each-function-to-complete-before-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!