user2066880
user2066880

Reputation: 5034

Applying delay between each iteration of jQuery's .each() method

Having some problems with the following block of code:

        $('.merge').each(function(index) {
            var mergeEl = $(this);
            setTimeout(function() {
                self.mergeOne(mergeEl, self, index - (length - 1));
            }, 500);
        });

I'm trying to apply a .500 second delay between each call of mergeOne, but this code only applies a .500 second delay before calling mergeOne on all the elements in the array simultaneously.

If someone could explain why this code doesn't work and possibly a working solution that would be awesome, thanks!

Upvotes: 6

Views: 926

Answers (1)

Ian
Ian

Reputation: 50905

Here's a general function you can use to iterate through a jQuery object's collection, with a delay between each iteration:

function delayedEach($els, timeout, callback, continuous) {
    var iterator;

    iterator = function (index) {
        var cur;

        if (index >= $els.length) {
            if (!continuous) {
                return;
            }
            index = 0;
        }

        cur = $els[index];
        callback.call(cur, index, cur);

        setTimeout(function () {
            iterator(++index);
        }, timeout);
    };

    iterator(0);
}

DEMO: http://jsfiddle.net/7Ra9K/ (loop through once)

DEMO: http://jsfiddle.net/42tXp/ (continuous looping)

The context and arguments passed to your callback should be the same as how .each() does it.

If you want to make it a jQuery plugin, so it can be called like $("selector").delayedEach(5000, func..., then you could use this:

$.fn.delayedEach = function (timeout, callback, continuous) {
    var $els, iterator;

    $els = this;
    iterator = function (index) {
        var cur;

        if (index >= $els.length) {
            if (!continuous) {
                return;
            }
            index = 0;
        }

        cur = $els[index];
        callback.call(cur, index, cur);

        setTimeout(function () {
            iterator(++index);
        }, timeout);
    };

    iterator(0);
};

DEMO: http://jsfiddle.net/VGH25/ (loop through once)

DEMO: http://jsfiddle.net/NYdp7/ (continuous looping)


UPDATE

I added the ability to continuously loop through the elements, as an extra parameter. Passing true will continuously loop, while passing false or nothing (or something falsey) will only loop over the elements once. The code and fiddles include the changes.

Upvotes: 8

Related Questions