What I want is this (news ticker type functionality):
As Greg mentioned the problem is with the closure only evaluating once. Nobody posted a solution for this so here is one. This uses adding a function that generates the callback function each time:
Add:
function getShowTextCallback(text) {
return function(){showText(text)}
}
Then use it in loop like this:
for(var x=0; x < li.length; x++){
var li_text = li[x].childNodes[0].nodeValue;
setTimeout(getShowTextCallback(li_text), 1000);
}
Change this:
for(var x=0; x < li.length; x++){
var li_text = li[x].childNodes[0].nodeValue;
setTimeout(function(){showText(li_text)}, 1000);
}
To:
for(var x=0; x < li.length; x++) (function() {
var li_text = li[x].childNodes[0].nodeValue;
setTimeout(function(){showText(li_text)}, x * 1000);
})()
How about we just move some of the code around a bit... take out the closure issue...
var ul = document.getElementById('post_list');
var li = ul.getElementsByTagName('li');
for (var x = 0, xl = li.length; x < xl; x++) {
var li_text = li[x].innerText || li[x].textContent; // does IE support textContent??
showText(li_text, x * 1000);
}
function showText(text, delay) {
setTimeout(function() {
console.log(text);
}, delay);
}
I assume the delay you want to be sequential (hence the loop). Because setTimeout is not blocking you will need to have a callback on the function to invoke the next setTimeout or you will need to specifically increment each function call with a new delay.
The reason this is happening is because of closures. The for loop block has closures around it, so when you reference 'li_text' it was always equal the last value that li_text was set to. The for loop does not create a separate closure for each iteration through the loop.