In a place where your fantasy can roam free, there won't be any boundaries to what your imagination can create.
Misha’s Tech Playground
graphics, fun and code play
I'm crazy - but who cares? My ideas are constantly dwelling and this is the place for them to pour out and form into something good. Only active participation will ultimately make this place come to life.
Dynamically loading external Javscript Files
Some weeks ago I read a short tutorial over at JavaScript Kit about how to load JavaScript files into your document on demand. This was a thought that I already pursued for some time as I had seen something similar already in the Scriptaculous Library. The difference on the Scriptaculous side was that you appended the additional files you wanted to load as a parameter to the main scripts url (scriptaculous.js?load=effect,dragdrop).
The idea is basically great. In modern languages you have the ability to import or include files for compilation (i.e. the C Family Languages, Java and Actionscript) or at runtime (i.e. Python and PHP).
So why should JavaScript be any different ?
Mainly it is because JavaScript wasn't designed with such behavior in mind . JavaScript wasn't supposed to build big applications like the now so popular Web 2.0 Apps (i.e. Google Maps, Google Calendar and others).
Why would I want that?
Once you start to develop larger Applications with JavaScript (or other languages for that matter) you usually end up having the same functionality in different places. But you also have bits of code that are unique to certain parts.
What makes sense in my opinion is to split up your monolithic JavaScript files into pieces that are:
- easier to maintain
- faster to load
- more reusable
But once you split up your files it can get messy rather quick too. On some occasions I had 6 or more Script nodes in one HTML file. Also keeping track of dependencies gets difficult.
Wouldn't it be a lot easier to have just a single script node where you would define what you need? Or better yet, let the script itself take care of what it needs.
How to do it?
I stumbled upon a great concept today that takes the initial idea a bit farther. A few days ago Remy Sharp blogged how to do On Demand Script Loading. Since I was working on the same idea I found this extremely interesting.
His idea is basically probes for the existence of an object and if it isn't found loads it.
My idea however was more similar to the initially mentioned Scriptaculous or Java approach.
You would need just a single script node in your html file to load either some
-
<script src="_js/opencsg/opencsg.js?load=event,input,util" [more attributes]></script>
for all your scripts.
-
<script src="_js/opencsg/opencsg.js" [more attributes]></script>
Okay, up until now this doesn't work different from Scriptaculous. So what I did further was to add a check for script dependencies.
For example I have one script that deals solely with event handling. Though this script is dependent on methods to check for different browsers and searching for nodes. I make a check if this object exists and if not I'll simply load it.
-
if (!CSG.CLASSES.util) {
-
CSG.include('util');
-
};
These checks are implemented in each file to make sure all dependencies are met. And since these checks are performed only when the script is loaded there is no performance hit.
The include function in turn looks like this:
-
include: function(libName) {
-
var src = CSG.path + libName + ".js";
-
-
if ((document.createElement && document.getElementsByTagName("head")[0].appendChild)) {
-
// insert script nodes to head node in all compatible browsers
-
var s = document.createElement("script");
-
s.setAttribute("type","text/javascript");
-
s.setAttribute("src", src);
-
document.getElementsByTagName("head")[0].appendChild(s);
-
} else {
-
// inserting via DOM fails in Safari 2 and other older browsers
-
document.write('<script type="text/javascript" src="' +src+ '"><\/script>' );
-
}
-
CSG.CLASSES[libName] = true;
-
}
Only the script name is submitted as parameter. Anything else is already stored in the object at the initial load.
Also note the fallback for browsers that have problems with inserting nodes via DOM.
This is just part of the whole script, though you could use this function independently. Once I have removed the kinks and quirks of this library I'll post the full version here too.
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.