In a place where your fantasy can roam free, there won't be any boundaries to what your imagination can create.
Misha’s Tech Playground
graphics, fun and code play
I'm crazy - but who cares? My ideas are constantly dwelling and this is the place for them to pour out and form into something good. Only active participation will ultimately make this place come to life.
Having a busy animation in Javascript
Looking into my logs recently I noticed that lots of people come here to find out how they can add an animated ellipsis or a spinning circle animation to show that their script is busy. Although I already showed how to do Progress monitoring with JavaScript on a more advanced level, I'll try to show how to do the very basic task of showing that your script is currently working. Keep in mind, if you know how much your script has to do (e.g. how many iterations) always aim to give the user accurate feedback about the current process.
Obviously the spinning circle (or any other animated image for that matter) is really easy:
Just before you call your computation intensive code, have an animated Gif containing your animated circle show up on your site. that's how Lightbox does it and that's how Greybox does it. I assume that is the same how Google does it as well. Once your busy function has completed you can just remove the Gif from the page or set it's display property to none.
The animated ellipsis could be done with an image as well, but we can also do it as text.
Not the most elegant but the easiest way would be to use an array with the different ellipsis states and have a function that refreshes the content of an element with this arrays contents.
-
var ellipsis = ['', '.', '..', '...'];
-
var runEllipsis = false;
-
-
function animateEllipsis(el, count) {
-
el.innerHTML = ellipsis[count%4];
-
if(runEllipsis == true) {
-
window.setTimeout( function(){
-
animateEllipsis(el, ++count);
-
}, 250);
-
}
-
}
-
-
function startEllipsis() {
-
runEllipsis = true;
-
animateEllipsis(document.getElementById('ellipsisSpan'), 0);
-
}
-
-
function stopEllipsis() {
-
runEllipsis = false;
-
}
-
-
function busy() {
-
startEllipsis();
-
// do something big that takes utterly long
-
stopEllipsis();
-
}
In the html file you would need a span element that gets updated anytime your busy animation is called. something like this would suffice:
Again, the problem you might face with this approach, since JavaScript is single threaded. You won't see an animation if you use a loop. Instead use a recursive approach to your problem with utilizing timeout as described in my previous post about Progress Monitoring with JavaScript.
That's it...
Update April 6th 2008
Upon Chris' request I created two examples for an animated ellipsis. One using the method above that sets a timeout for each time the ellipsis is updated. Though, this method uses innerHTML is therefore not truly dom compliant and to my knowledge uses lots of resources (to process the inner html).
I have therefore made an optimized version which uses elm.textContent for the ellipsis and an interval for the update which should save lots of overhead produced by repeated calls to setTimeout.
I also rectified a bug in the code that caused the animation not to show.
Thanks to Chris for pointing that out!
Tags: code performance
6 Responses to “Having a busy animation in Javascript”
Leave a Reply
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.
Superb! This is EXACTLY what I needed for a web-app I'm building. However, I'm having some problems implenting it and I'm not sure why.
The page I'm building uploads a local client file to a server. The form for dates/files is on the default, displayed div. While the HTML page POSTs the data to a PHP script, I hide the form div and display a different div that just says "Uploading...". And the ellipsis at the end is where I'd like to have your code animate it a bit.
When the file is done uploading, the last line in the PHP script just refreshes the HTML page, so the form div is displayed again. I can't seem to get it to work. IE6 keeps complaining that 'the object does not support the or method'. I don't recall if it was protocol or something else, I was working on this at work and I'm on linux at home so I can't verify this.
I'm getting no animation, and in fact no periods displaying at all. Could this be a browser compatibility issue? I've checked and re-checked my (your) code, no typos, everything is exactly as it should be.
Is there any POSSIBLE way I might be able to convince you to add a demo on your site? I've scoured the web and haven't really been able to find a working example of something like this.
Hi Chris,
I am happy it was of help to you. The error you encountered was that I mixed up document and window on line 15 of the script. Everything is now corrected and per your request, 2 examples are added as well.
Have fun and check back often
Many thanks, friend! I have yet to test this in my app as Sunday and Mondays are my days off, but when I return to work tomorrow I'll certainly give it a try and report my findings. I like the new version as well, now I just need to decide which to go with!
Thanks again!
Well, I tried pulling up the demo for the new version at work, not functioning on IE6. I checked it at home using the Epiphany browser (more or less same Gecko engine as Firefox) and it worked just fine. Gotta love M$....
Anyhoo, I've got the original, with the fix, working perfectly now! Again, thank you for taking the time to post demos and check the code. I really appreciate that.
Yeah, IE probably has a problem with elm.textContent it instead uses elm.innerText. I didn't know that though...
There is a cool page dealing with migrating from IE to Mozilla, but it's good too if you want to get stuff to work in IE that already runs well in Mozilla.
Migrating Apps from IE to Mozilla
I've also just remembered that textContent isn't dom compliant either, so I changed the second example to use elm.firstChild.nodeValue instead, which references the value of the textnode within the paragraph element.
Though, keep in mind that you'll need at least a single space in your markup code to get this to work or you'll have to add the text node after the page has loaded manually.
Maybe this will work now
Very interesting blog, i have added it to my fovourites, greetings