4
votes

I am having trouble getting my jquery function to complete, before calling the next function.

Essentially, I am trying to get my news articles to fade out, and finish all the fadeout animations before then retrieving the next page of articles via ajax.

Heres what I have (Sampled to include only the functions concerned).

A function to control the fading out of each news article...

function fadeArticlesOut() {
    var delay = 0;
    //set timeout for image to appear (set at 500ms)
    $('#news-articles article').each(function(index) {
        $(this).delay(delay).fadeTo(800, 0);
        delay += 400;       
    })
};          

A function which is triggered by clicking a pagination link. This captures the url to load via ajax, but before it does so, this is where I want to run the fadeout function, i.e fadeArticlesOut. What I want is for the fade out animations to have finished before running the loadProducts function.

function doPager() {
    $('.pagination-controls a').click(function(e) {
        e.preventDefault();

        fadeArticlesOut();          
        loadProducts($(this).attr('href'));
        history.pushState(null, null, $(this).attr('href'));
        historyedited = true;
    });
}

function loadProducts(url) {
    $('#news-articles').empty().addClass('loading').load(url + ' #news-articles-inner', function() {
        $('#news-articles').removeClass('loading');
        doPager();
        fadeArticlesIn();
    });
}

Once completed, the load products function will then fade in the new news articles.

So far, I have tried numerous methods including using a custom callback, deferred objects and setting timeouts. The issue I have is I can either get it to run the fadeouts, but then not continue with the ajax content load, or not have the fadeouts, but get the ajax content.

1
Look into deferred objects/the Promise object. You can add a .done() function handler after your fadeTo() call and that will trigger when the fade is complete.Derek

1 Answers

7
votes

You can get a promise by using .promise() and then add a .done() handler.

function fadeArticlesOut() {
    ...
    return $('#news-articles article').each(function(index) {
      ...
    }).promise();
};  

function doPager() {
    $('.pagination-controls a').click(function(e) {
        var $self = $(this);
        ...
        fadeArticlesOut().done(function(){
            loadProducts($self.attr('href'));
        });          
        ...
    });
}

The .done() handler will be called upon all animations are completed.