jqueryfor-looploadappendjquery-callback

jQuery callback after append


I have the following code:

HTML

<div id="body"></div>

JS

var site = { 'pageData' : [
    {   
        'loadInTo'      :   '#aboutUs',
        'url'           :   'aboutUs.html',
        'urlSection'    :   '.sectionInner'
    },
    {   
        'loadInTo'      :   '#whatWeDo',
        'url'           :   'whatWeDo.html',
        'urlSection'    :   '.sectionInner' 
    },
    {   
        'loadInTo'      :   '#ourValues',
        'url'           :   'ourValues.html',
        'urlSection'    :   '.sectionInner' 
    },
    {   
        'loadInTo'      :   '#ourExpertise',
        'url'           :   'ourExpertise.html',
        'urlSection'    :   '.sectionInner' 
    }   
]}

for(i=0; i < site.pageData.length; i++) {
    var loader = site.pageData[i];

    $('#body').append('<div id="'+ loader.loadInTo +'" class="section" />');
    $(loader.loadInTo).load(loader.url + ' ' + loader.urlSection);      
}

What I am doing is looping through the site variable and writing out some div's using jQuery's append method that have the id set in 'loadInTo', this works fine. After this is complete I want to use jQuery's load method to populate the divs with HTML from other pages. Is there a to make a callback after appending the div's? something like this:

$('#body').append('<div id="'+ loader.loadInTo +'" class="section" />', function(){
        $(loader.loadInTo).load(loader.url + ' ' + loader.urlSection);
    });

Solution

  • jQuery doesn't support a callback for .append. Also, it's much more efficient to append the data at once, rather than calling .append for each element. See the code below.

    Every element-to-append is added to a string. Once the string has finished, a marker is added, and the HTML is appended. Then, a poller is activated, checking whether the marker element exist in the DOM. If it exists, the poller is cleared, the marker is removed, and the code executes.

    Update: .substr(1) is used when the ID is set, because the ID shouldn't be prefixed by #.

    var toAppend = '';
    var markerID = 'mark-end-of-append' + (new Date).getTime(); //Random
    for(var i=0; i<site.pageData.length; i++) {
        var loader = site.pageData[i];
        toAppend += '<div id="'+ loader.loadInTo.substr(1) +'" class="section" />';
    }
    toAppend += '<div id="' + markerID + '"></div>';
    $('#body').append(toAppend);
    var poller = window.setInterval(function(){
        var detected = document.getElementById(markerID);
        if(detected){ //DOM is much more efficient
            window.clearInterval(poller);
            $(detected).remove(); //Remove marker
            for(var i=0; i<site.pageData.length; i++){
                var loader = site.pageData[i];
                $(loader.loadInTo).load(loader.url + ' ' + loader.urlSection);
            }
        }
    }, 100); //Check 10x per second