jqueryasp.netasynchronousmaster-pageslabjs

Using Lab.js in master page to load jQuery asynchronously and then using jQuery code in child files


I use LAB.js to load JQuery asynchronously in asp.net master page. The problem is that I use

$( document ).ready(function() {
    //something
}); 

and other JQuery dependent code in almost all child pages, which makes script error: ($ is undefined) because JQuery is being loaded asynchronously in the master page.

How can I defer parsing jQuery code in child pages until the asynchronous loading of jQuery is completed in the master page?

The problem is the asynchronous loading of JQuery from the Master page and using some JQuery code in the child pages. How can that be done?


Solution

  • NOTE: Don't make the mistake of conflating $.ready(..) with "jquery is ready", as many do. $.ready(..) tells you when the document itself is ready (fully parsed), whereas script loading (especially the dynamic kind with libs like LABjs) is entirely separate. Here, you're really looking for "is jquery loaded/ready", which should be handled by your script loader if possible. You may also need to wait for the document to be ready, in which case you should also use $.ready(..). But don't substitute one for the other!


    The simplest way (but not necessarily the best) is to declare a global variable in the master page that holds the LAB chain that's loading the main jquery file, then chain off that in your child pages. So in master page:

    var $jqLoading = $LAB.script("jquery.js");
    

    And in child pages:

    $jqLoading.wait(function(){
       // my jquery code goes here
    });
    

    Another option is to rely on LABjs de-duping script requests (default behavior), so just attempt the load of jquery in each child, but use the same URL as the parent did, and LABjs will make sure only one copy of jquery gets loaded, but all chains waiting on it will get notified once that one load finishes. So, in child pages:

    $LAB.script("jquery.js").wait(function(){
       // my jquery code goes here
    });
    

    This may be slightly less efficient, but it avoids needing a global variable, which is better design IMO.


    The most sophisticated solution is to use something like a promise to represent the loading of the jQuery script, and then chain of that promise in each child page. That's beyond what we'll cover here, but there's plenty out there about promises if you're interested in learning about them.