Long task in Javascript / jQuery
I have a long task in Javascript that should be performed before the web page content is displayed. During the execution of this task I would like to show an image whose opacity will grow up to 100% (when the task is done). How thi开发者_C百科s can be achieved ?
In your function , say it's 10 loops, every loop you need to increase the opacity, like this:
var curOpacity = 0;
function doWork(step) {
for(var j = 0; j <100000000; j++) { } //simulate work
console.log("Completed step: " + step);
$("#element").css('opacity', step * 0.1);
if(step < 10)
setTimeout(function() { doWork(step + 1); });
}
doWork(0);
You can see a working demo here
On the final step this would be setting the opacity to 1
, completely faded in. The steps you just need to divide out, you need to increase opacity by 1/numOfSteps
each step...a .fadeIn()
won't work here because it'll just execute after your code is done...you need to manually set the opacity using .css()
inside the loop.
The setTimeout()
(without an argument it's instant) lets the UI update before the next step starts.
Note: this works cross-browser, just use opacity
and it'll take care of setting filter:
in IE for instance.
Decompose the task into multiple smaller tasks, each of which updates the progress bar appropriately. Then schedule these sub-tasks to run asynchronously using something like the jQuery Async extension. Without the async component, your tasks will hog the CPU until they are finished, and you won't see any interim status updates.
Depending on your requirements DOMContentLoaded Event might be called too late. Please notice the fact that that event is triggered when the whole DOM tree has been loaded. In some cases a web browser might start display web content before </html>
is reached. You could just please some JavaScript right after <body>
element (document.body
is available there, while others DOM elements are not).
Any method you choose the rest of the code stays practically the same.
So now you have to:
Create an image and inject it into DOM tree:
var img = document.createElement("img"); img.setAttribute("src", "/path/to/the/image.png"); document.body.appendChild(img);
Make that image transparent:
img.style.opacity = "0";
Start your task
Every time the task is one percent closer to the end increase the value of the image's opacity style:
img.style.opacity = Math.min(1, (img.style.opacity * 1) + 0.01); // Of course you can increase by any step, not only 0.01 (1%)
The problem may be the determination of when the task is one step closer to the end. If that task is for example a loop which repeats 10 times then there is easy way to determine it - every single iteration the task progress jumps 10%. But if your task has more complex structure then I think you'll have to define by your own places where task progress is 10, 20, 25, 50, 100%.
task(0);
//download something using AJAX
task(30);
while (i = 0..10) { ... task(+5) }
doSomething();
task(80);
doSthElse();
task(100);
Use web workers in modern browsers and partition the task with setTimeout()
in old ones.
精彩评论