Matei Gheorghiu
Matei Gheorghiu

Reputation: 45

setTimeout not working after hours of research.

I have been looking for answers for hours and it seems that my problem is with closure. I could not figure out how to fix it in my scenario. I want to trigger an animation onload on 6 elements, all 1000ms apart. I can't get the setTimeout method to work properly. Please help!

$(document).ready(function() {
    we();
});

var data = ['450px', '300px', '200px', '120px', '250px', '320px'];
var bars = $('.bar');
var i = 0;

function grow(size, elem) {
    $(elem).animate({
        height: size,
        opacity: '1.0'
    }, 1000);
}


function we() {

    setTimeout (function(){ // if I don't use an annonymous function call here, they all animate at the same time
        grow(data[i], bars[i]);
    }, 1000);

    if (i >= bars.length) {
        return;
    } else {
        i++;
        return we();
    };
}

Upvotes: 2

Views: 1560

Answers (1)

Jakob
Jakob

Reputation: 24360

You have to put your setTimeout around the rest of your function as well; not just the call to grow.

function we() {
    setTimeout (function(){
        grow(data[i], bars[i]);

        if (i >= bars.length) {
            return;
        } else {
            i++;
            return we();
        };
    }, 1000);
}

I think what you've missed is that setTimeout does not block your program. It doesn't stop execution, wait for 1000 ms and then continue. Instead, it will delay the execution of the anonymous function for 1000 ms, but the rest of the program will continue to execute right away. And that part of your program will call we once again, and schedule a new animation (almost at the same time as the last one). And then another and so on.

By putting the recursive call inside setTimeout, we delay the recursion as well and hence all future animation steps.

Upvotes: 5

Related Questions