Monday 16 July 2007

Loading dependencies in JavaScript

Isn't it nice to work modularized, even in JavaScript?
I like putting all my classes in their own files and all the little functions that don't belog to any class in a file called toolbox.js

That's pretty neat and organized, but when it comes to inserting all the necessary js files into your webpage, it's a pain, isn't it?

Well, not for me. I add the toolbox.js to every webpage that uses JavaScript and then the most important js file for that particular page.

Here's an example; I have a webpage that needs to use the EntryModule class. But this class needs a few more classes that are stored in other files, the TableEntryClass, the TextEntryClass and ColourObjectClass. All I need to do is to call this function:

loadDependencies(Array('js/ColourObjectClass.js', 'js/TableEntryClass.js', 'js/TextEntryClass.js'));

This function takes either a string or an array of strings that specify the js files to add to the same webpage that loaded EntryModuleClass.js

Here's the code, use it wise:

function loadDependencies(dependency)
{
  var head = document.getElementsByTagName('head')[0];
   var scripts = head.getElementsByTagName('script');
  var i, j, newjs;
  if(typeof dependency == 'string')
  {
    //search if it's loaded already
    for(i=0; i < scripts.length; ++i)
      if(scripts[i].src.toLowerCase() == dependency.toLowerCase())
        return;
    //if not, load it
    newjs = document.createElement('script');
    newjs.type = 'text/javascript';
    newjs.src = dependency;
    head.appendChild(newjs);
  }
  if(typeof dependency == 'object')//it must be an array
  {
     //search if it's loaded already
     for(i=0; i < dependency.length; ++i)
     {
       for(j=0; j < scripts.length; ++j)
         if(scripts[j].src.toLowerCase() == dependency[i].toLowerCase())
           return;
       //if not, load it
       newjs = document.createElement('script');
       newjs.type = 'text/javascript';
       newjs.src = dependency[i];
       head.appendChild(newjs);
     }
   }
}

I hope you notice the care I took with declaring the variables at the begining of the function and also getting the head tag and the script tags at the begining to optimize the number of searches...

No comments: