1

I've found a few other questions pertaining to this, but the answers didn't work for me, so I'm checking to see if there's anything newer or something that will work. Essentially, I'm updating divs in a .each in jQuery, but I want them to update a couple seconds apart. Here's what I've tried:

function randomColor() {
$('div').each(function(i) {

    setTimeout(function() { 
        var colors = ['blue', 'green'];
        var n = Math.floor(Math.random() * colors.length);
        var color = colors[n];
        $(this).addClass(color);
    }, 500 + (i * 500));
});
}

I've also tried using a separate function:

function randomColor() {
$('div').each(function(i) {
    var time = 500;
    setTimeout(function() { 
        applyColor($(this)); 
    }, time);
    time += 500;
});
}
function applyColor(div) {
    var colors = ['blue', 'green'];
    var n = Math.floor(Math.random() * colors.length);
    var color = colors[n];
    $(div).addClass(color);
}

Both of these return no errors, but the divs don't get updated. If I run this code without the setTimeout, it works perfectly. I've also tried using delay in this fashion:

$('div').delay(1000).each(function() {
...
});

And that delayed by 1 second, but then updated everything at once after that second. If I move the delay down near the addClass line, it stops working altogether again. Can anyone point out this (hopefully simple) mistake?

Kyle
  • 67
  • 7
  • possible duplicate of [How to add pause between each iteration of jQuery .each()?](http://stackoverflow.com/questions/5202403/how-to-add-pause-between-each-iteration-of-jquery-each) – Dhiraj Apr 09 '15 at 22:46
  • @DhirajBodicherla I did see that question, and the answer didn't help me. I did do a lot of searching before posting, as I mentioned at the beginning – Kyle Apr 09 '15 at 22:47

3 Answers3

4

You're creating an anonymous function and inside that function this has a different meaning (i.e., the window object).

One solution is to cache this:

var $this = $(this);
setTimeout(function() { 
    var colors = ['blue', 'green'];
    var n = Math.floor(Math.random() * colors.length);
    var color = colors[n];
    $this.addClass(color);
}, 500 + (i * 500));
Stryner
  • 7,288
  • 3
  • 18
  • 18
  • Thank you for the quick response! I did this and it worked perfectly. I'll accept the answer once the time limit is up. Thanks so much for your help! – Kyle Apr 09 '15 at 22:52
1

I think what you want to do is:

function randomColor() {
  var colors = ['blue', 'green'];
  var n = Math.floor(Math.random() * colors.length);
  var color = colors[n];
  $('div').each(function() {
    $(this).delay(1000).addClass(color);
  });
});

When fuction is run, it would randomly pick a Class name ('blue' or 'green'). It would then update the DIV after waiting 1 second. Then move to the next in the Each loop.

Twisty
  • 30,304
  • 2
  • 26
  • 45
1

Here's an example using setTimeout and an increment'er to loop over the divs, rather than the jQuery each method.

JSFiddle

(function randomColorDiv(ii) {

    var colors = ['blue', 'green']
    var n = Math.floor(Math.random() * colors.length)
    var color = colors[n]
    $($('div')[ii]).addClass(color)

    if ( ii < $('div').length ) {
        setTimeout(function() { 
            randomColorDiv(++ii)
        }, 1000)
    }

}(0))
bloodyKnuckles
  • 11,551
  • 3
  • 29
  • 37