Shawn Mclean
Shawn Mclean

Reputation: 57469

Structure javascript and delay execution when dynamically loading scripts

I'm loading my javascript files using Modernizr.load(). Now lets say each page needs to call their own init method after everything has finished loading. But I put the loading in a template master, which is unaware of the child pages. How can the pages know when the dependencies have finished loading?

script

Page1Stuff= {
   init: function(){ alert('page 1 executed'); }
}
Page2Stuff= {
   init: function(){ alert('page 2 executed'); }
}

site master template

//Modernizr loads the script.
Modernizr.load([{
    load: 'jquery.js',
},
{
    load: 'script.js'
}]);

page1

$(function() {
    Page1Stuff.init();
});

page2

$(function() {
    Page2Stuff.init();
});

I think I see 2 problems here. If modernizr is still loading jquery, $ may not be defined. Also, Page2Stuff or Page1Stuff may not be defined.

Upvotes: 0

Views: 413

Answers (1)

Charles Ma
Charles Ma

Reputation: 49171

In your template: Use the modernizer "complete" call back to emit a custom event to signal the loading is complete, also set a global variable saying that the scripts have been loaded.

In your page scripts: first check the global variable to see if all scripts have been loaded, if not, register a handler to listen for the custom event you emit when the loading completes.

In your template code:

// A simple object that calls its listeners when modernizer script loading completes.
global_scriptLoadingMonitor = (function() {
   var listeners = [];
   var isComplete = false;
   return {
      "addListener": function (listener) {
         listeners[listeners.length] = listener;
      },
      "complete": function () {
         isComplete = true;
         for (var i = listeners.length - 1; i >= 0; i--) {
            listeners[i]();
         }
      },
      "isComplete": isComplete
   }
})();

Modernizr.load([{
    load: 'jquery.js',
},
{
    load: 'script.js'
    complete: function () {
    {
       global_scriptLoadingMonitor.complete();
    }
}]);

Now in your Page1 do this:

if (global_scriptLoadingMonitor.isComplete) {
    $(function() {
        Page1Stuff.init();
    });
} else {
    global_scriptLoadingMonitor.addListener(function() {
        $(function() {
           Page1Stuff.init();
        });
    });
}

And similarly for page2.

Upvotes: 2

Related Questions