Daniel Gretzke
Daniel Gretzke

Reputation: 446

Updating DOM during Javascript function execution

I have a long running Javascript function, that looks like this:

window.myFunction = function() {
    for(var i=0;i<500;i++){
        // calling a function here
        document.getElementbyID('mySpan').innerHTML = "Completed step " + i + "/500"
    }
}

My function calls another synchronous function very often (I used 500 in this example) and while the user waits for the task to complete, i'd like to implement something like a loading bar but I demonstrated it with updating a span in my case here. Is it possible to force a DOM refresh of some sort every time I update my span?

Upvotes: 5

Views: 1945

Answers (2)

Thusitha
Thusitha

Reputation: 3511

You should use a setTimeout method to run it on the event queue rather than run it on the stack. Because you won't see the updates inside a for loop since it runs without a delay. I added a callback to run it after a heavy task.

//Heavy task function
var heavyTask = function(i, callback) {
  setTimeout(function() {
    document.getElementById('mySpan').innerHTML = "Completed step " + i + "/500";

    //Callback to the caller saying the task is finished here and continue on
    /////////////////////
    callback();

  }, 50);
}


var i = 0;

//Call myFunction recursively.
(window.myFunction = function() {
  if (i < 500) {
    heavyTask(i, function() {
      i++;
      window.myFunction();
    });
  }
})();
<span id="mySpan"></span>

Upvotes: 2

Reinstate Monica Cellio
Reinstate Monica Cellio

Reputation: 26143

Since scripts run in a single thread in your browser, any method like yours will need to complete before the DOM is updated. What you can do, however, is use an iterative function with a small delay that allows the browser to redraw.

Here's an example...

window.myFunction = function(i) {
    // calling a function here - passing i as a parameter, if needed
    document.getElementById('mySpan').innerHTML = "Completed step " + i + "/500";
    i++;
    if (i <= 500) setTimeout(function() { myFunction(i) }, 1);
}

myFunction(0);
<span id="mySpan"></span>

Upvotes: 4

Related Questions