How to show loading spinner in jQuery?

889,539

Solution 1

There are a couple of ways. My preferred way is to attach a function to the ajaxStart/Stop events on the element itself.

$('#loadingDiv')
    .hide()  // Hide it initially
    .ajaxStart(function() {
        $(this).show();
    })
    .ajaxStop(function() {
        $(this).hide();
    })
;

The ajaxStart/Stop functions will fire whenever you do any Ajax calls.

Update: As of jQuery 1.8, the documentation states that .ajaxStart/Stop should only be attached to document. This would transform the above snippet to:

var $loading = $('#loadingDiv').hide();
$(document)
  .ajaxStart(function () {
    $loading.show();
  })
  .ajaxStop(function () {
    $loading.hide();
  });

Solution 2

For jQuery I use

jQuery.ajaxSetup({
  beforeSend: function() {
     $('#loader').show();
  },
  complete: function(){
     $('#loader').hide();
  },
  success: function() {}
});

Solution 3

You can just use the jQuery's .ajax function and use its option beforeSend and define some function in which you can show something like a loader div and on success option you can hide that loader div.

jQuery.ajax({
    type: "POST",
    url: 'YOU_URL_TO_WHICH_DATA_SEND',
    data:'YOUR_DATA_TO_SEND',
    beforeSend: function() {
        $("#loaderDiv").show();
    },
    success: function(data) {
        $("#loaderDiv").hide();
    }
});

You can have any Spinning Gif image. Here is a website that is a great AJAX Loader Generator according to your color scheme: http://ajaxload.info/

Solution 4

If you are using $.ajax() you can use somthing like this:

$.ajax({
  url: "destination url",
  success: sdialog,
  error: edialog,
  // shows the loader element before sending.
  beforeSend: function() {
    $("#imgSpinner1").show();
  },
  // hides the loader after completion of request, whether successfull or failor.             
  complete: function() {
    $("#imgSpinner1").hide();
  },
  type: 'POST',
  dataType: 'json'
});

Although the setting is named "beforeSend", as of jQuery 1.5 "beforeSend" will be called regardless of the request type. i.e. The .show() function will be called if type: 'GET'.

Solution 5

You can insert the animated image into the DOM right before the AJAX call, and do an inline function to remove it...

$("#myDiv").html('<img src="images/spinner.gif" alt="Wait" />');
$('#message').load('index.php?pg=ajaxFlashcard', null, function() {
  $("#myDiv").html('');
});

This will make sure your animation starts at the same frame on subsequent requests (if that matters). Note that old versions of IE might have difficulties with the animation.

Good luck!

Share:
889,539
Angry Dan
Author by

Angry Dan

web/software developer, .NET, C#, WPF, PHP, software trainer, English teacher, have philosophy degree, love languages, run marathons my tweets: http://www.twitter.com/edward_tanguay my runs: http://www.tanguay.info/run my code: http://www.tanguay.info/web my publications: PHP 5.3 training video (8 hours, video2brain) my projects: http://www.tanguay.info

Updated on November 21, 2020

Comments

  • Angry Dan
    Angry Dan over 3 years

    In Prototype I can show a "loading..." image with this code:

    var myAjax = new Ajax.Request( url, {method: 'get', parameters: pars, 
    onLoading: showLoad, onComplete: showResponse} );
    
    function showLoad () {
        ...
    }
    

    In jQuery, I can load a server page into an element with this:

    $('#message').load('index.php?pg=ajaxFlashcard');
    

    but how do I attach a loading spinner to this command as I did in Prototype?

  • montrealist
    montrealist almost 15 years
    That's probably too global for one simple load into a DIV.
  • nickf
    nickf almost 15 years
    too global? how many different "please wait" messages do you want?
  • uriDium
    uriDium about 14 years
    Top tip: Preload the spinner.gif in a div with display set to none. Otherwise you might get a bit of a delayed spinner effect as the spinner still downloads.
  • glaz666
    glaz666 over 13 years
    this way unfortunately you can't control loading div positioning in case you don't want to just show a modal loading window, but show it near the element waiting for ajax content to be loaded in...
  • David Xia
    David Xia about 13 years
    ajaxStart and ajaxStop are jQuery events so you can namespace them: stackoverflow.com/questions/1191485/… docs.jquery.com/Namespaced_Events
  • Gordon Thompson
    Gordon Thompson about 13 years
    nice tip, much simpler than using somebody else's plugin
  • Tim Büthe
    Tim Büthe over 12 years
    You could have timing problems there, don't you?
  • Jaseem
    Jaseem over 12 years
    @UltimateBrent I think you got it wrong. Why is showLoad() not a callback? JavaScript will load content asynchronously. showLoad() will work even before the content is loaded if i'm correct.
  • Jaseem
    Jaseem over 12 years
    One plugin for this simple task? That is not really a good solution is it? Who wants to load 100 scripts on a page?
  • Jaseem
    Jaseem over 12 years
    It will be hard to manage UI this way. We may need completely different styles for the "loading" text and final message. We can use the callback method mentioned above for handling this problem
  • yigal
    yigal over 12 years
    works for me, the html should have something like: <div id='loader'><img src="spinner.gif"/></div>
  • Both FM
    Both FM over 12 years
    Nice! but dear , one thing more that I want to display spinner for 2 seconds even the page has already loaded.
  • Josh Stodola
    Josh Stodola about 12 years
    @BothFM Because people enjoy waiting for things...?
  • Scott
    Scott about 12 years
    Agreed. Compress and concatenate, if you want better performance.
  • Lee Goddard
    Lee Goddard almost 12 years
    Disagreed: separate and modularise, reuse code, if you want to be able to maintain your work and have others do so too. What the chance of your user having such a poor connection their client can't load a plugin as well as your code?
  • Lee Goddard
    Lee Goddard almost 12 years
    The success won't be called if there is an error, but "you will always receive a complete callback, even for synchronous requests," according to jQuery Ajax Events.
  • Travis J
    Travis J almost 12 years
    This is very clear, +1! @glaz666 - That is not true. It is all about how you configure it. For example: .ajaxStart(function(e) { CallFunctionWithTargettedElement(e.currentTarget); }) will call a function where the argument is the element which initiated the ajax call. Note that this is just an example with no handling for if the ajax was called from a script without an event handler or any other error checking whatsoever. It is merely to show that there are ways of controlling the positioning. The function called could place an absolute element over the calling element.
  • deckoff
    deckoff over 11 years
    This works for me only the first time I trigger the query, second and next times the animation does not show. any ideas?
  • nickf
    nickf over 11 years
    @deckoff it only triggers when an ajax request is started and there were no ajax requests still active.
  • Joel Peltonen
    Joel Peltonen over 11 years
    @Jaseem I use a similar method too and it actually relies on async calls. I would place showLoad somewhere before the ajax call but the whole point is to show a spinner, let JS start the call, and kill the spinner in a callback after the AJAX has completed.
  • kenswdev
    kenswdev over 11 years
    This one was cleanest for me. Instead of ajaxSetup, I placed beforeSend: and complete: inside the $ajax({... statement.
  • Dom M.
    Dom M. over 11 years
    If using jQuery >= 1.9, attach the ajaxStart and ajaxStop events to $(document). jquery.com/upgrade-guide/1.9/…
  • pec
    pec almost 11 years
    Don't know what it's worth, but jQuery mentions in it's documentation that using .ajaxSetup() is not recommended. link
  • nickf
    nickf over 10 years
    Note here that beforeSend is called before every call, whereas ajaxStart is triggered only when the first ajax method is called. Likewise for ajaxStop, it is called when the last ajax call finishes. If you have more than one concurrent request, the snippet in this answer won't work properly.
  • Sergey Orshanskiy
    Sergey Orshanskiy about 10 years
    Does not work for me if the ajax call times out (Firefox 28 for Mac).
  • SpringLearner
    SpringLearner about 8 years
    @NathanBubna The link is dead
  • Izabela Skibinska
    Izabela Skibinska over 7 years
    Shortest way would be to insert image tag with an image downloaded from ajaxload.info with transparent background
  • mercury
    mercury over 7 years
    ajaxSetup is like general setting for ajax reauests
  • andrew oxenburgh
    andrew oxenburgh over 6 years
    "What the chance of your user having such a poor connection their client can't load a plugin as well as your code?" Pretty good I'd say.
  • Matt
    Matt almost 6 years
    Really nice! Especially if you take a look at the demos ... Disable DOM elements, In Tag, Full Overlay, Element Overlay ... it provides everything you need. And you can easily combine Full Overlay with this answer to get it working instantly.
  • ankush981
    ankush981 over 2 years
    But you need to hide the spinner on error as well.