Nicros
Nicros

Reputation: 5183

Chaining dynamically loaded javascript

I have a static page that I'm trying to add jQuery and the BlockUI plugin to. jQuery needs to be loaded first before I can use BlockUI, and while I can load jQuery just fine, I cant seem to get BlockUI to load after and call its loaded handler so I can do the work. I do see the BlockUI script tag in my html page, so it is at least being injected in okay as far as I can see. Here's my code:

var jqueryScript = document.createElement( "script" );
jqueryScript.src = "/glptools/scripts/jquery-1.9.1.min.js";
if ( jqueryScript.addEventListener ) {
    jqueryScript.addEventListener( "load", jqueryReady, false );
}
else if ( jqueryScript.readyState ) {
    jqueryScript.onreadystatechange = jqueryReady;
}
document.getElementsByTagName( 'head' )[0].appendChild( jqueryScript );

function jqueryReady() {
    if ( typeof jQuery != 'undefined' ) {
        $( document ).ready( function () {
            //Initialize Tabber
            tabberAutomatic( "" );

            // Add BlockUI plugin
            var blockUIScript = document.createElement( "script" );
            blockUIScript.src = "/glptools/scripts/blockui/jquery.blockUI.js";
            if ( blockUIScript.addEventListener ) {
                blockUIScript.addEventListener( "load", blockUIReady, false );
            }
            else if ( blockUIScript.readyState ) {
                blockUIScript.onreadystatechange = blockUIReady;
            }
            document.getElementsByTagName( 'head' )[0].appendChild( blockUIScript );
        } );
    }
}

function blockUIReady() {
    $( "#tabbertabhide" ).each( function ( index, elem ) {
        $( elem ).block();
    } );
}

My goal is to use BlockUI to block the tabs located on my page. I tried putting the block ui load code outside the ready() call, but then the loaded handler gets called before jQuery has been loaded.

Upvotes: 0

Views: 776

Answers (3)

Vivin Paliath
Vivin Paliath

Reputation: 95518

If BlockUI depends on jQuery, you will need to load it sequentially. You can do something like this:

//This function creates a script element using "resource" and
//adds it to the head. callback is used as the onload callback
//for the script
function loadScript(resource, callback) {
    var head = document.getElementsByTagName("head")[0];
    var script = document.createElement("script");

    script.type = "text/javascript";
    script.src = resource + "?t=" + new Date().getTime(); //prevent caching

    if (callback) {
        script.onload = callback;
    }

    head.appendChild(script);
}

//Array of scripts to load
var resources = [
        "/glptools/scripts/jquery-1.9.1.min.js",
        "/glptools/scripts/blockui/jquery.blockUI.js"
];

//This function will load the scripts one after the other, using a callback
//that calls this function itself.
function load(i) {
    if(i < resources.length) {
        loadResource(resources[i], function() {                
            load(++i);
        });
    } else {
        //Everything has finished loading so you can start
        //using jQuery and BlockUI
    }
}

load(0);

Upvotes: 1

Vadim
Vadim

Reputation: 8789

As far as both jQuery and BlockUI are located in the same origin as your page you can get jQuery and BlockUI scripts as text, concat them and add to document as merged script. Just like this:

function createXMLHttp() {
  //Initializing our object
  var xmlHttp = null;
  //if XMLHttpRequest is available then creating and returning it
  if (typeof(XMLHttpRequest) != undefined) {
    xmlHttp = new XMLHttpRequest;
    return xmlHttp;
  //if window.ActiveXObject is available than the user is using IE...so we have to create the newest version XMLHttp object
  } else if (window.ActiveXObject) {
    var ieXMLHttpVersions = ['MSXML2.XMLHttp.5.0', 'MSXML2.XMLHttp.4.0', 'MSXML2.XMLHttp.3.0', 'MSXML2.XMLHttp', 'Microsoft.XMLHttp'];
    //In this array we are starting from the first element (newest version) and trying to create it. If there is an
    //exception thrown we are handling it (and doing nothing)
    for (var i = 0; i < ieXMLHttpVersions.length; i++) {
        try {
            xmlHttp = new ActiveXObject(ieXMLHttpVersions[i]);
            return xmlHttp;
        } catch (e) {
        }
    }
  }
}

function getData(url, callback) {
  var xmlHttp = createXMLHttp();
  xmlHttp.open('get', url, true);
  xmlHttp.send(null);
  xmlHttp.onreadystatechange = function() {
    if (xmlHttp.readyState === 4) {
      if (xmlHttp.status === 200) {
        callback(xmlHttp.responseText);
      }
    }
  };
}

getData('/glptools/scripts/jquery-1.9.1.min.js', function(jQuery) {
  getData('/glptools/scripts/blockui/jquery.blockUI.js', function(blockUi) {
    var head = document.getElementsByTagName("head")[0],
        script = document.createElement('script');
    script.innerHTML = jQuery + ';' + blockUi;
    head.appendChild(script);
  });
});

Upvotes: 1

MDerks
MDerks

Reputation: 123

You should consider use of script loader such as http://requirejs.org/ or http://headjs.com/ which can resolve dependecies tree for you and make code cleaner.

Upvotes: 2

Related Questions