i got a client side javascript function which is triggered on a button click (basically, its a calculator!!). Sometimes, due to enormous data on the page, the javascript calculator function take to long & makes the page appear inactive to the user. I was planning to display a transparent div over entire page, maybe with a busy indicator (in the center) till the calculator function ends, so that user waits till process ends.
function CalculateAmountOnClick() { // Display transparent div // MY time consuming loop! { } // Remove transparent div }
Any ideas on how to go about this? Should i assign a css class to a div (which surrounds my entire page's content) using javascript when my calculator function starts? I tried that but didnt get desired results. Was facing issues with transparency in IE 6. Also how will i show a loading message + image in such a transparent div?
TIA
I'm going to make some heavy assumptions here, but it sounds to me what is happening is that because you are directly locking the browser up with intense processing immediately after having set up the curtain element, the browser never has a chance to draw the curtain.
The browser doesn't redraw every time you update the DOM. It may woit to see if you're doing something more, and then draw what is needed (browsers vary their method for this). So in this case it may be refreshing the display only after it has removed the curtain, or you have forced a redraw by scrolling.
A fair waring: This kind of intense processing isn't very nice of you because it not only locks up your page. Because browsers generally implement only a single Javascript thread for ALL tabs, your processing will lock up all open tabs (= the browser). Also, you run the risk of the execution timeout and browser simply stopping your script (this can be as low as 5 seconds).
Here is a way around that.
If you can break your processing up into smaller chunks you could run it with a timeout (to allow the browser breathing space). Something like this should work:
This is essentially a while loop but each iteration of the loop is done in an timed interval so the browser has a bit of time to breathe in between. It will slow down the processing though, and any work done afterwards needs to go into a callback as the loop runs independently of whatwever may follow the call to processLoop.
Another variation on this is to set up the curtain, call your processing function with a setTimeout to allow the browser time to draw the curtain, and then remove it once you're done.
If you are using a js-library, you may want to look at a ready made solution for creating curtains. These should exist for most libraries, here is one for jQuery, and they can help with the CSS.
For the loading message, I would use a
<div>
withposition:absolute
, position it usingleft
andtop
, and set the display tonone
.When you want to show the loading indicator, you're going to have to use a timeout otherwise the
div
won't display until your processing is done. So, you should modify your code to this:Because you set the timeout, the page will redraw before the time-consuming loop happens.
Javacript to show a curtain:
Your CSS:
(Move MSIE 6 underscore hacks to conditionally included files as desired.)
You could set this up as add/remove functions for the curtain, or as a wrapper:
Which you could then call like this:
In addition to all of the above, don't forget to put an invisible iframe behind the shim, so that it shows up above select boxes in IE.
Edit: This site, although it provides a solution to a more complex problem, does cover creating a modal background. http://www.codeproject.com/KB/aspnet/ModalDialogV2.aspx
I would do something like:
display:inline
)position:absolute
z-index:99
100%
display:none
To make it transparent you'll have to set the opacity which is different in Firefox, IE, etc.
To show a loading icon you can always create a second div and position it where you want to on the page. When it's done loading, remove it along with the transparent one.