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