elad.chen
elad.chen

Reputation: 2425

setTimeout produces a scope error

My question is simple. I'm using setTimeout inside a for loop, during runtime an error is produced saying:

Uncaught TypeError: Cannot call method 'setAttribute' of undefined

My experience with javascript is slim (I'm skipping jQuery for the sake of learning) and I assume this has something with the way I'm calling setTimeout.

Take a look at my function, I would like to know why "elements" is not available from inside the anonymous function.

function hide_visable_elements()
{
    // remove body EventListener
    var body = document.getElementsByTagName("body");
    body[0].removeEventListener("click", hide_visable_elements, true);

    var elements = document.getElementsByClassName("visible");
    for (var i = 0; i < elements.length; ++i)
    {
    elements[i].removeAttribute("class");
    setTimeout(function() { elements[i].setAttribute("class", "hidden") }, 300);
    }   
}

Upvotes: 0

Views: 71

Answers (1)

Esailija
Esailija

Reputation: 140210

Here's an example of how you could capture the current value of the iteration so that when it is executed after the loop has completed (it always is after, because of the asynchronous nature), it will do the right thing:

function setHidden(element) {
    return function() {
        element.setAttribute("class", "hidden");
    };
}

function hide_visable_elements() {
    // remove body EventListener
    var body = document.getElementsByTagName("body");
    body[0].removeEventListener("click", hide_visable_elements, true);
    var elements = document.getElementsByClassName("visible");
    for (var i = 0; i < elements.length; ++i) {
        elements[i].removeAttribute("class");
        setTimeout(setHidden(elements[i]), 300);
    }
}


Btw I'm using the description "long after" relatively, the minimal amount of time that passes before your deferred functions could possibly be executed is 4 or 13 milliseconds but the loop execution time is measured in micro or nano seconds.

Upvotes: 1

Related Questions