No Page Rendering While Img Onload-event In Javascript
Solution 1:
Unless you go with background Web Workers massaging (more complicated, espacially in your situation), the rendering of your progress bar can only occur after a complete return from your script; therefore, after each showProgress
call. Now, how to return, render then restart for the remaining? Well, that's where a setTimeout
of 0 millisecond comes handy. With it, the following should work:
img.onload = function() {
showProgress('Preparing image...' .1);
setTimeout(function() {
// Some preparations...
showProgress('Preparing tools...', .2);
setTimeout(function() {
// etc...
showProgress('Done...', 1);
}, 0);
}, 0);
}
An alternative approach to nesting code would be a kind of recursive call - yet each call will complete before the following will start - on an array of steps, like this:
steps = [
function() { // first step (img loading just completed so, show Preparing it right away)
showProgress('Preparing image...', .1);
},
function() { // second step
// Some preparations...
showProgress('Preparing tools...', .2);
}, // other steps...
function() { // last step
// Last things to do...
showProgress('Done...', 1);
}
];
// function that processes "steps" - array of at least 1 function - until empty
function displayAfterEachStep() {
steps.shift()(); // Pull out the first step and run it
if(steps.length > 0) // if there's still steps
setTimeout(displayAfterEachStep, 0); // Recall the process after page rendering
}
img.onload = displayAfterEachStep;
Many other good ideas to get around that lack of Rendered Event in HTML can be found here and around.
Solution 2:
I came back to the matter after working on some other projects and solved my problem using Promises
like this:
showProgress("Loading image...", 0.0) // Reset progress bar
const img = document.createElement("img") // Get image element
const promise = new Promise((resolve, reject) => { // Instantiate a Promise
img.onload = resolve // Set onload callback to resolve (this triggers the chain)
img.onerror = reject
img.src = "/path/to/image.jpg" // Set src attribute to start loading image
})
.then(() => { // When promise is resolved: Start step 2
showProgress("Preparing image...", 0.3)
// ...
})
.then(() => { // When promise is resolved: Start step 3
showProgress("Preparing tools...", 0.6)
// ...
})
.then(() => { // When promise is resolved: Finish up
showProgress("Ready...", 1)
// ...
})
With Promises
you can put asynchronous tasks in an order while still maintaining readability.
Further reading: Promises on MDN
Post a Comment for "No Page Rendering While Img Onload-event In Javascript"