It's a psychological phenomena that waiting takes less time as long as
something happens.
I'm sure you have seen all these nice rotating arrows, bouncing points or bars that
are commonly used for situations where a progress bar should appear to
tell the user that it's time for waiting like on the windows start up screen on
http://www.pageflakes.com/
or even in windows media edition. It can also be as simple as the [Loading...] text
that is used by the Google-Mail user interface.
So, when I fell over http://www.ajaxload.info
last week where you can easily generate "AJAX-" animated gif files I thought it is time
to implement a few lines into the AJAX Engine.
The right place to start displaying a progress indicator is just before starting the
webservice call to the server. Here I call StartProgress().
But it also has to be hidden after anything happens that
ends the action like when the return value is there, an exception happens or when the
timeout timer strikes. To identify these places I searched the code for the ajax.current
gets cleared. There I call EndProgress();
The first implementation was straight forward creating and removing a html element.
After some testing I found that this costs me more time than the real call over the
internet and in many situations immediate responses got slower and that's definitively not
that what I wanted to achieve.
In the end I came to the following solution:
- The StartProgress function only sets a flag
(ajax.progress) to true and starts a timer (ajax.progressTimer) with a timeout
of 220 msec.
- This time was chosen by some testing and many server
calls do not last so long and therefore need no progress indicator.
- When the timer strikes it calls the ajax.ShowProgress
function. Here I implement the real code that creates the HTML element or just
shows an existing one again.
- The EndProgress function clears the flag and also
starts the timer but with some less waiting.
- When the timer strikes after a call has finished the
existing object is just hidden.
This architecture has some advantages. First the progress indicator is not shown when short calls are made and
when multiple calls are made one after the other it is not hidden.
This can save a lot of flickering.
Here are the specific new functions:
// ----- show or hide a progress indicator -----
// show a progress indicator if it takes longer...
ajax.StartProgress = function() {
ajax.progress = true;
if (ajax.progressTimer != null)
window.clearTimeout(ajax.progressTimer);
ajax.progressTimer = window.setTimeout(ajax.ShowProgress, 220);
} // ajax.StartProgress
// hide any progress indicator soon.
ajax.EndProgress = function () {
ajax.progress = false;
if (ajax.progressTimer != null)
window.clearTimeout(ajax.progressTimer);
ajax.progressTimer = window.setTimeout(ajax.ShowProgress, 20);
} // ajax.EndProgress
// this function is called by a timer to show or hide a progress indicator
ajax.ShowProgress = function() {
ajax.progressTimer = null;
var a = document.getElementById("AjaxProgressIndicator");
if (ajax.progress && (a != null)) {
// just display the existing object
a.style.top = document.documentElement.scrollTop + 2 + "px";
a.style.display = ";
} else if (ajax.progress) {
// find a relative link to the ajaxcore folder containing ajax.js
var path = "../ajaxcore/"
for (var n in document.scripts) {
s = document.scripts[n].src;
if ((s != null) && (s.length >= 7) && (s.substr(s.length -7).toLowerCase() == "ajax.js"))
path = s.substr(0,s.length -7);
} // for
// create new standard progress object
a = document.createElement("div");
a.id = "AjaxProgressIndicator";
a.style.position = "absolute";
a.style.right = "2px";
a.style.top = document.documentElement.scrollTop + 2 + "px";
a.style.width = "98px";
a.style.height = "16px"
a.style.padding = "2px";
a.style.verticalAlign = "bottom";
a.style.backgroundColor="#51c77d";
a.innerHTML = "<img style='VERTICAL-ALIGN:bottom' src='" + path + "ajax-loader.gif'> please wait...";
document.body.appendChild(a);
} else if (a) {
a.style.display = "none";
} // if
} // ajax.ShowProgress
You can find the full source
here
and I will also include it into the next ajax.zip.
If you want to see how it looks like you can use the old prime factor sample.
Try some long the numbers like: 98798798789878987. You might see it only if
someone else is stressing the server too - It seems to be a powerful machine :-) and
prime factors get calculated fast even with my stupid algorithm :-).