Search code examples
jqueryajaxfunctionloadwait

jQuery / AJAX - loading content into modal window, how to wait until load() is finished?


here's my function that is being called from within a .click(function { loadBox(url); }); on a button:

var loadBox = function(url) {
    var mask = $('#mask');
    var box = $('#box');
    $(mask).fadeTo(600, 0.8).promise().done(function() {
        var winH = $(window).height();
        var winW = $(window).width();
        var boxH = winH * 0.6;
        var boxW = winW * 0.8;

        $(box).css({
            width: boxW + 'px',
            height: boxH + 'px',
            top: ((winH - boxH) / 2) + 'px',
            left: ((winW - boxW) / 2) + 'px'
        });

        $(box).load(url).promise().done(function () {
            $(box).slideDown(300);
        });

        $(mask).click(function() {
            if($(':animated').length)
                return false;
            $(this).hide();
            $(box).hide();
        });
    });
}

#mask/$(mask) is a <div>-container that is just being used as an overlay, #box/$(box) is another <div>-container that is loading a *.php page via $(box).load(url)... where url is something similiar to /pages/player.php?match_id=1&player_id=15.

Thus far it seems to be working, only one little thing is dirsturbing me, regarding:

$(box).load(url).promise().done(function () {
    $(box).slideDown(300);
});

I have a table with different players in it, when you click on a player's name #box pops up in the center of the screen, loaded with the player.php holding information about that player.

But if #box was loaded with some other player's information before, box will first show ($(box).slideDown(300);) and afterwards its content is changed - so you see the other player's information for about half a second before the new information is loaded.

I thought <function>.promise().done(... will wait till until <function> - in my case .load(url) is completed and only then execute everything within the .done(function { }); scope, or am I incorrect?

What is the correct way to wait until the .load(url) call is finished before showing the $(box) using .slideDown()?


Solution

  • In this case, you should use a callback function. When .load completes its task, it will fire the callback. So, you should change:

    $(box).load(url).promise().done(function () {
        $(box).slideDown(300);
    });
    

    to:

    $(box).load(url, function () {
        $(box).slideDown(300);
    });
    

    Also, you don't need to keep wrapping box in a jQuery method. This defeats the purpose of caching them in vars at the top of your script. So really, it should be:

    box.load(url, function () {
        box.slideDown(300);
    });
    

    Same goes for other instances in your code where you're wrapping vars multiple times...