4

So I am trying to write a javascript script to dynamically load pages on my site without refreshing the page. Basically I have a function which fades out the content div, loads the new content, switches the content, then fades it in. The content is loaded using an asynchronous AJAX request, which on success calls the function that fades the content in. The fadein function should not run until the load function AND the fadeout function are both done. I want the page to be loading the whole time the content is fading out, but right now my fading animation is frozen. I've tried a bunch of different ways to figure this out but nothing is working so far...

Any ideas?

TWGerard
  • 885
  • 1
  • 10
  • 24
  • possible duplicate of [Wait for two events with jQuery and execute a callback when both are done](http://stackoverflow.com/questions/10469292/wait-for-two-events-with-jquery-and-execute-a-callback-when-both-are-done) – T.J. Crowder May 10 '12 at 21:32
  • Can you show a minimal representation of the code to reproduce the problem? – David May 10 '12 at 21:33

3 Answers3

2

This is just a matter of waiting for two events to complete and, when they're both complete, taking action. See my answer to this other question. Basically:

Have a flag for each event, initially false. Hook the two events in question (the completion callback on the animation, and the ajax success). Each event sets its flag and calls a function. That function checks the flags: If both are set, it does something (in your case, sets the new content). See the link for a code example.

Community
  • 1
  • 1
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • 1
    This worked perfectly!!!! BRILLIANT!!! Honestly I did not think I had even given enough information for anybody to be able to help me on this. I was going to update it later, but now I don't have to. You are AWESOME, sir. Well done. – TWGerard May 10 '12 at 21:51
  • 1
    Thanks for that tip! If you'd like to see what I'm working on you can check it out at tylergerard.com It's not nearly finished, but I just got the animated transitions working and I kind of want to show it off. – TWGerard May 11 '12 at 01:10
1

I have a site which does something similar. The function to slide out, replace content, and slide in is as follows:

var loadAnAjaxArticle = function (url) {
    var removeParentArticle = function () {
        // I don't like doing this, but so far haven't found a
        // particularly elegant way to replace the article
        // when calling load(), only append it.
        $('article').first().html($('article').last().html());
    };

    var showArticle = function (response, status, xhr) {
        if (status == "error") {
            $('article').first().html('<h2>There was an error processing your request.</h2>');
            $('article').first().slideDown('slow');
        } else {
            removeParentArticle();
            $('article').first().slideDown('slow');
        }
    };

    var loadArticle = function () {
        $('article').first().load(url + ' article', showArticle);
    };

    $('article').first().slideUp('slow', loadArticle);
}

Basically, it calls .slideUp to hide the content, providing a call-back to another function. That function calls .load to refresh the content, providing a call-back to another function. That function does a little manipulation of the DOM to make it look right (it's early in development, I haven't made it more elegant yet), and calls .slideDown to show the content again.

This is easy to do in this case because each function I'm using accepts a call-back. If the functions you're using have the same capability, you should be able to chain them in this manner.

David
  • 208,112
  • 36
  • 198
  • 279
  • That doesn't do both things at once; it just waits to do the second thing (loading the new article) until the first (the slide up) finishes. That means wasting the user's time. Much better to overlap the two and then take action when both have finished. – T.J. Crowder May 10 '12 at 21:45
1

You just need to set a flag and have both completion functions check to see if both events are done. Whichever completion function finds both are done, triggers the next action.

You haven't give us any specifics of your code, but here's the general idea:

function loadNewPage(args) {

    var fadeDone = false;
    var ajaxData;

    function processAjaxDataWhenReady() {
        // if both have completed, then process the ajaxData and start the fadeIn
        if (fadeDone && ajaxData) {
            // process the ajaxData here
            $("#myContent").fadeIn();
        }
    }

    // start the fadeOut
    $("#myContent").fadeOut(function() {
        fadeDone = true;
        processAjaxDataWhenReady();
    });

    // start the ajax call
    $.ajax({...}, function(data) {
        ajaxData = data;
        processAjaxDataWhenReady();
    })

}
jfriend00
  • 683,504
  • 96
  • 985
  • 979