opticon
opticon

Reputation: 3594

jQuery/JavaScript Execution Order

I have some items that I'd like the user to be able to filter using jQuery. The user selects their filter criteria and hits submit, and I make a call to my database. When this call completes, I fade out the existing containers with this function:

function clearGrid() {
    var theseDivs = $('.grid-item');
    $('.grid-item').fadeOut('fast', function() {
    $(theseDivs).remove();      
    }); 
}

and then I append my new data with the following function:

function repopulate() {
    <% @stuff.each do |gb| %>
    $('#grid').append('<%= escape_javascript(render "/stuff", :gb => gb) %>');
    <% end %>
    resizeGrid();
}

The resizeGrid() function does some absolute positioning based on the other elements in the Grid. It seems like repopulate() is being called BEFORE the other elements are removed with clearGrid(), and thus the positioning of the new elements is off, and they're rendered as if the old elements are still there.

Is there a way to ensure that my repopulate() function doesn't get called until the other elements are well out of the way?

Upvotes: 1

Views: 104

Answers (2)

Nathan Friedly
Nathan Friedly

Reputation: 8146

You should allow the clearGrid() function to call a callback once it's completed, and then pass it repopulate as that callback. Change clearGrid() to look like this:

function clearGrid(callback) {
    var theseDivs = $('.grid-item');
    theseDivs.fadeOut('fast', function() {
        theseDivs.remove();
        if(callback) {
            callback();
        }
    }); 
}

And then, assuming your current code to call those two looks like this:

clearGrid();
repopulate();

You can change it to look like this:

clearGrid( repopulate );

Note: repopulate should not have () after it because you want to pass a reference to it, not call it.

Second note: I also changed clearGrid() to just use theseDivs rather than call jQuery again. It's slightly faster this way, although you probably won't be able to notice the difference.

If you know that there will only ever be <div> tags that you're working with, you could change the selector to $('div.grid-item') for another small speedup.

Upvotes: 1

Matthew Blancarte
Matthew Blancarte

Reputation: 8301

Try slowing down the repopulate method with

setTimeout( function(){ repopulate(); }, 50 );

Upvotes: 0

Related Questions