Reputation: 2425
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
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