Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

setTimeout inside for loop [duplicate]

I want a string to appear character-for-character with the following code:

function initText()
{
    var textScroller = document.getElementById('textScroller');
    var text = 'Hello how are you?';

    for(c = 0; c < text.length; c++)
    {
        setTimeout('textScroller.innerHTML += text[c]', 1000);
    }
}

window.onload = initText;

It's not working.. what am I doing wrong?

like image 964
richard Avatar asked Nov 21 '09 20:11

richard


People also ask

Can I use setTimeout in for loop?

setTimeout function in JavaScript usually takes a callback function as an argument. A callback function is a function that is executed after another function finishes running. In this case, it will run after for loop finishes.

How many times does setTimeout () execute the function parameter?

As specified in the HTML standard, browsers will enforce a minimum timeout of 4 milliseconds once a nested call to setTimeout has been scheduled 5 times.

Is setTimeout in a different thread?

No, it doesn't. "Execution context" doesn't mean "thread", and until recently Javascript had no support for anything resembling threads. What actually happens is that an event is pushed onto the event queue that's set to execute in the number of milliseconds specified by the second argument to SetTimeout/SetInterval.

Does setTimeout block execution?

Explanation: setTimeout() is non-blocking which means it will run when the statements outside of it have executed and then after one second it will execute. All other statements that are not part of setTimeout() are blocking which means no other statement will execute before the current statement finishes.


2 Answers

Try something like this:

function initText()
{
    var textScroller = document.getElementById('textScroller');
    var text = 'Hello how are you?';

    var c = 0;
    var interval = setInterval(function() { 
                          textScroller.innerHTML += text[c]; 
                          c++; 
                          if(c >= text.length) clearInterval(interval);
                   }, 1000);

}

Note I added clearInterval to stop it when it's needed.

like image 87
Soufiane Hassou Avatar answered Oct 04 '22 16:10

Soufiane Hassou


Currently, you are defining 18 timeouts and all will be executed ~ at once. Second problem is, you pass instructions to execute as a String. In that case, the code won't have access to all variables defined in initText, because evaluated code will be executed in global scope.

IMO, this should do the job

function initText(){
    var textScroller = document.getElementById('textScroller');
    var text = 'Hello how are you?';

    var c = 0;

    (function(){
        textScroller.innerHTML += text.charAt(c++);
        if(text.length > c){
            setTimeout(arguments.callee, 1000);
        }
    })();
}
like image 20
Rafael Avatar answered Oct 04 '22 16:10

Rafael