views:

3262

answers:

4

I would like to place a "please wait, loading" spinning circle animation on my site. I'm having trouble to find a plugin for it, so here I am asking a weird question :)

Thank you for your help.

+1  A: 

You can grab an animated GIF of a spinning circle from Ajaxload - stick that somewhere in your website file heirarchy. Then you just need to add an HTML element with the correct code, and remove it when you're done. This is fairly simple:

function showLoadingImage() {
    $('#yourParentElement').append('<div id="loading-image"><img src="path/to/loading.gif" alt="Loading..." /></div>');
}

function hideLoadingImage() {
    $('#loading-image').remove();
}

You then just need to use these methods in your AJAX call:

$.load(
     'http://example.com/myurl',
     { 'random': 'data': 1: 2, 'dwarfs': 7},
     function (responseText, textStatus, XMLHttpRequest) {
         hideLoadingImage();
     }
);

// this will be run immediately after the AJAX call has been made,
// not when it completes.
showLoadingImage();

This has a few caveats: first of all, if you have two or more places the loading image can be shown, you're going to need to kep track of how many calls are running at once somehow, and only hide when they're all done. This can be done using a simple counter, which should work for almost all cases.

Secondly, this will only hide the loading image on a successful AJAX call. To handle the error states, you'll need to look into $.ajax, which is more complex than $.load, $.get and the like, but a lot more flexible too.

Samir Talwar
Thanks for the reply. But tell me, why do I need to use AJAX at all?Can't I simply track down it all in the page itself?
thedp
What exactly do you want to track? Unless you're requesting information after the page has loaded (and AJAX is pretty much the only way to do that without using a plugin), why would you need a "loading" image at all?
Samir Talwar
Samir Talwar: A heavy JavaScript application actually. Thanks, I get the idea.
thedp
Understandable. In that case, just call `showLoadingImage` before you start and `hideLoadingImage` after you finish. Should be fairly simple. You may need to stick some sort of `setTimeout` call in to make sure the browser actually renders the new `<img>` tag though - I've seen a couple of cases where it doesn't bother until the JavaScript has finished executing.
Samir Talwar
+12  A: 

Generally this is done by showing/hiding a div or two over the top of your content. You can get a fancy loading gif from http://www.ajaxload.info/ to get you started. Then you'll want to place a DIV on your page:

<div id="loading">
  <p><img src="loading.gif" /> Please Wait</p>
</div>

You'll want this hidden by default, so you'd need to add this CSS:

#loading { display:none; }

You'd also want to setup the display for this too:

#loading { display:none; position:fixed; left:0; top:0; width:100%; height:100%;
           background-image:url("transparentbg.png"); }

The file transparentbg.png would be a 25x25 black PNG set to about 80% opaque. Next you would need a way to show and hide this with jQuery:

function showLoading() {
  $("#loading").show();
}

function hideLoading() {
  $("#loading").hide();
}

Now you can use this when you need to do something like querying an external page for data:

showLoading();
$.post("data.php", {var:"foo"}, function(results){
  $("content").append(results);
  hideLoading();
});
Jonathan Sampson
This is the most in depth solution although I'd recommend you use a centering plugin which centers the preloader around a page element (*i.e. body, #element, or .element*)
cballou
That would be a nice addition, cballou. I was merely trying to keep the information minimized - but as you point out, it certainly can be improved upon.
Jonathan Sampson
Instead of using an additional div, it's also worth noting you can just make a class for one of the elements that is near the location you want to display the image, and use the same technique, sans an extra div.
Sneakyness
A: 

jQuery provides event hooks for when AJAX requests start and end. You can hook into these to show your loader.

For example, create the following div:

<div id="spinner">
  <img src="images/spinner.gif" alt="Loading" />
</div>

Set it to display: none in your stylesheets. You can style it whatever way you want to. You can generate a nice loading image at Ajaxload.info, if you want to.

Then, you can use something like the following to make it be shown automatically when sending Ajax requests:

$(document).ready(function () {

    $('#spinner').bind("ajaxSend", function() {
     $(this).show();
    }).bind("ajaxComplete", function() {
     $(this).hide();
    });

});

Simply add this Javascript block to the end of your page before closing your body tag or wherever you see fit.

Now, whenever you send Ajax requests, the #spinner div will be shown. When the request is complete, it'll be hidden again.

Veeti
Can someone please explain what AJAX has to do with this? Can't I simply manage this all within the page without accessing the server with AJAX... Or am I missing here something? Thanks.
thedp
Ah - as I understood, you wanted a loading image to be shown whenever you were making AJAX requests. If you simply want a "please wait, loading..." animation to be shown until the page has fully loaded, you could have a loading div in the page and then hide it in your $(document).ready block.
Veeti
+4  A: 

Along with what Jonathan and Samir suggested (both excellent answers btw!), jQuery has some built in events that it'll fire for you when making an ajax request.

There's the ajaxStart event

Show a loading message whenever an AJAX request starts (and none is already active).

...and it's brother, the ajaxStop event

Attach a function to be executed whenever all AJAX requests have ended. This is an Ajax Event.

Together, they make a fine way to show a progress message when any ajax activity is happening anywhere on the page.

HTML:

<div id="loading">
  <p><img src="loading.gif" /> Please Wait</p>
</div>

Script:

$("#loading").ajaxStart(function(){
    $(this).show();
 }).ajaxStop(function(){
    $(this).hide();
 });
Dan F
That's brilliant. Had no idea these existed.
Samir Talwar