Lazy Javascript Loader
I was involved in a project recently with some heavy use of Javascript. We needed to load many javascript files on the page. Because of the site structure and the legacy system, there are potential situations where the same javascript is loaded more than once. To over come that, we needed something that can handle the script loading for us.
After looking at many options, we decided to write our own quick and dirty lazy script loader which will fit our need.
The key features we want from it are:
- Dynamically creating a script tag to load any scripts we want
- Handle callbacks
- Handle duplicate script load
- Small in size and simple api
- Framework independent
Usage Example:
ScriptLoader.load('demo.js', function() { alert('Demo script loaded Loaded'); });
Code:
//namespace var ScriptLoader = {}; //scripts object storing the state and callbacks of scripts ScriptLoader.scripts = {}; //Handle multiple script callbacks to one single script ScriptLoader.onScriptLoad = function(url) { var script = this.scripts[url]; script.loaded = true; for (var i = 0, len = script.callbacks.length; i < len; i++) { var callback = script.callbacks[i]; if (typeof callback != 'undefined') callback(); } }; //Main loader function ScriptLoader.load = function(url, callback) { //Check if script has already been added to the loader if (this.scripts[url] != undefined) { if (this.scripts[url].loaded) //File loaded { //Run callback straight away if (typeof callback != 'undefined') callback(); } else //Still loading { //Add callback to list for running later this.scripts[url].callbacks.push(callback); } //Script already requested so exit here return; } //Create tracker for this script to monitor status and build a list of callbacks this.scripts[url] = {loaded: false, callbacks: [callback]}; //Add script element to DOM and add onload handlers for callbacks var script = document.createElement("script") script.type = "text/javascript"; if (script.readyState) //IE { script.onreadystatechange = function() { if (script.readyState == "loaded" || script.readyState == "complete") { script.onreadystatechange = null; ScriptLoader.onScriptLoad(url); } }; } else //Other browsers { script.onload = function(event) { ScriptLoader.onScriptLoad(url); }; } script.src = url; document.getElementsByTagName('head')[0].appendChild(script); };
This is by no mean to be ground breaking or prefect but it is working prefect for us on most popular browsers. There are many awesome fully featured script loading library out there. RequireJS is definitely one worth looking.
I also have to thanks Charles Davison co-author of the code and Bob Matsuoka as he gave us a good starting point for this script in his A Technique For Lazy Script Loading article from Ajaxian
Comments so far
Does this script stop multiple javascript files from conflicting? I’m having a problem on my site where only one script will work on the page.
It will only load the same script once as it will record all the scripts being loaded. But if there are conflicts in with different script, then there are not much this script can do…
Thanks for this Javascript Loader. Might as well try it to upload.
Post a comment