antonpug
antonpug

Reputation: 14296

Why is this javascript not running as expected?

    function animateGraph() {
    var graph;
    for(i=0; i<10; i++)
    {
        var start = new Date();
        while((new Date()) - start <= 500) {/*wait*/}
        document.getElementById("timeMark").innerHTML = phoneX[i].epoch;

    }
}

The loop works. The wait works. But the document.getElement is not showing up until the last item in the array...why?

Upvotes: 1

Views: 89

Answers (4)

Mattias Buelens
Mattias Buelens

Reputation: 20179

The following snippet uses a helper function to create the timers. This helper function accepts a loop counter argument i and calls itself at the end of the timer handler for the next iteration.

function animateGraph() {
    var graph;
    setTimeMarkDelayed(0);

    function setTimeMarkDelayed(i) {
        setTimeout(function() {
            document.getElementById("timeMark").innerHTML = phoneX[i].epoch;

            if (i < 10) {
                setTimeMarkDelayed(++i);
            }
        }, 3000);
    }
}

You actually need some sort of helper function, otherwise you'll end up overwriting the value of i in your for loop in every iteration and by the time your timers run out, i will already be 9 and all handlers will act on the last element in phoneX. By passing i as an argument to the helper function, the value is stored in the local scope of that function and won't get overwritten.

Or you could use setInterval like Radu suggested, both approaches will work.

Upvotes: 0

Bergi
Bergi

Reputation: 665122

The while loop, waiting for a datetime, is not a good way to wait - it just blocks execution. It keeps the browser (including UI, and its updating) frozen until the script finishes. After that, the window is repainted according to the DOM.

Use window.setTimeout() instead:

function animateGraph(phoneX) {
    var el = document.getElementById("timeMark")
    var i = 0;
    (function nextStep() {
        if (i < phoneX.length )
            el.innerHTML = phoneX[i].epoch;
        i++;
        if (i < phoneX.length )
            window.setTimeout(nextStep, 500);
    })();
}

Please note that this runs asynchronous, i.e. the function animateGraph will return before all phoneXes are shown.

Upvotes: 1

epascarello
epascarello

Reputation: 207537

Using setTimeout will allow the code to run and not lock up the page. This will allow it to run the code and will not effect other elements on the page.

var cnt = 0;
(function animateGraph() {
    document.getElementById("timeMark").innerHTML = phoneX[cnt].epoch;
    cnt++;
    if (cnt<10){
        window.setTimeout(animateGraph,500);
    }
})();

Upvotes: 5

Larry Battle
Larry Battle

Reputation: 9178

Use setTimeout instead of a while loop.

https://developer.mozilla.org/en/DOM/window.setTimeout

Also try something like this. Javascript setTimeout function

Upvotes: 0

Related Questions