0

I'm trying to adapt this solution to my needs: How can I create a "Please Wait, Loading..." animation using jQuery?

Basically a really awesome scheme is provided to wrap Ajax requests with a nice loading GUI. I'm trying to do the same for a function I have that does some calculations and then appends some graphics to the DOM.

So what I've tried is this:

$("body").addClass("loading");
long_time_taking_function(mainDiv);
$("body").removeClass("loading");

Unfortunately it appears as though the class is added and then removed instantly, either before or after the long_time_taking_function() executes. However I know that adding the class works, because commenting out the removeClass() call keeps the gif floating on the page.

Any ideas how I can make this work? I can provide more details about the intermediate function if needed.

Cheers

Community
  • 1
  • 1
JDS
  • 16,388
  • 47
  • 161
  • 224
  • Yes, the contents of `long_time_taking_function` would definitely be appreciated. – Zach Shipley Jul 30 '12 at 23:35
  • It does this: 1. Sort a big JSON object by a particular field 2. Create a highcharts object (http://www.highcharts.com/) and append it to the main div element That's all. – JDS Jul 30 '12 at 23:58
  • Where are you getting the big JSON object? – Zach Shipley Jul 31 '12 at 00:07
  • Generated from elsewhere.. It's actually a variable that's included in another .js file. – JDS Jul 31 '12 at 00:14
  • I see. In that case, I think it's quite possible that your `long_time_taking_function` does not take that long after all. Try profiling it by surrounding the call with `console.time('t1');` and `console.timeEnd('t1');` and viewing the console (F12 in Firefox or Chrome). – Zach Shipley Jul 31 '12 at 00:20

3 Answers3

3

This is a common pitfall with AJAX: the first "A" stands for "asynchronous". That means that the AJAX call returns immediately and runs more-or-less "in the background". long_time_taking_function() contains an AJAX call. You just need to move that $('body').removeClass('loading') into the callback of the AJAX call. If you're using jQuery (assuming you are since you tagged ), it will look something like this:

$.ajax({
    ...options...
}).always(function(response) {
    $('body').removeClass('loading');
});

Edit: the jQuery Deferred object's callback here should be always(), as the loading class should be removed even if the ajax call failed.

Zach Shipley
  • 1,092
  • 6
  • 5
  • I don't think I'm using AJAX though. Hence why I made this topic. All my function does is update the DOM by adding some javascript-generated images, does that count as AJAX? – JDS Jul 30 '12 at 23:51
1

You can add a call back to your function so that when it is finished, it will call your removeClass statement.

Something like this:

     //declare your functions
     function long_time_taking_function(mainDiv, callback){

        //...your code...
        callback();
     }

     function removeLoadGif(){
         $("body").removeClass("loading");
     }



     //in your current code call this
     $("body").addClass("loading");
     long_time_taking_function(mainDiv, removeLoadGif);

Or you could just add the line $("body").removeClass("loading"); to the end of your function long_time_taking_function. If the body currently doesn't have the class, it won't do anything.

RestingRobot
  • 2,938
  • 1
  • 23
  • 36
0

You need to do something like this...

$("body").addClass("loading");
doSomething(url,params)
  .complete(function() {
    $("body").removeClass("loading");
  });

In your code, addClass and removeClass are executed so fast it's like nothing ever happened.

Gil Birman
  • 35,242
  • 14
  • 75
  • 119