I've had a similar task a few days earlier, and here's how I did it.
This loader works both in file:// prefixes as well as in http:// and https://, and is cross-browser compatible.
It however, cannot load specific classes or functions as modules from scripts; it will load the whole script altogether and make it available to the DOM.
// Loads a script or an array of scripts (including stylesheets) // in their respective index order, synchronously. // By Sayanjyoti Das @https://stackoverflow.com/users/7189950/sayanjyoti-das var Loader={ queue: [], // Scripts queued to be loaded synchronously loadJsCss: function(src, onl) { var ext=src.toLowerCase().substring(src.length-3, src.length); if(ext=='.js') { var scrNode=el('script', null, null, null); scrNode.type='text/javascript'; scrNode.onload=function() {onl();}; scrNode.src=src; document.body.appendChild(scrNode); }else if(ext=='css') { var cssNode=el('link', null, null, null); cssNode.rel='stylesheet'; cssNode.type='text/css'; cssNode.href=src; document.head.appendChild(cssNode); onl(); } }, add: function(data) { var ltype=(typeof data.src).toLowerCase(); // Load a single script if(ltype=='string') { data.src=data.src; Loader.queue.splice(0, 1, data, Loader.queue[0]); Loader.next(); } // Load an array of scripts else if(ltype=='object') { for(var i=data.src.length-1; i>=0; i--) { Loader.queue.splice(0, 1, { src: data.src[i], onload: function() { if(Loader.next()==false) { data.onload(); return; } Loader.next(); } }, Loader.queue[0]); } Loader.next(); } }, next: function() { if(Loader.queue.length!=0 && Loader.queue[0]) { var scr=Loader.queue[0]; // Remove the script from the queue if(Loader.queue.length>1) Loader.queue.splice(0, 2, Loader.queue[1]); else Loader.queue=[]; // Load the script Loader.loadJsCss(scr.src, scr.onload); }else return false; } };
The above function is very powerful and elegant; it allows you to load a single script or an array of script synchronously (i.e, next script not loaded until previous script loading finished). Moreover, a loaded script may load more scripts, which defers the queue in the parent script.
BTW, a script here means a JavaScript file or a CSS stylesheet.
Here's how to use it:-
// Load a single script Loader.add({ src: 'test.js', onload: function() { alert('yay!'); } }); // Load multiple scripts Loader.add({ src: ['test1.js', 'test2.js', 'mystyles.css', 'test3.js'], onload: function() { alert('all loaded!'); } });
Note that, the onload function in the Loader arguments is called when all of the scripts have loaded, not when one or a single script is loaded.
You can also load more scripts in the scripts you loaded, such as in test.js, test1.js, etc. By doing this, you will defer the load of the next parent script and the queue in the child script will be prioritized.
Hope it helps :-)
<script>tags one after the other in the head of the document?file:///. I don't want to load megabytes of JSON until I know that the user needs the 5-word phrase file, but once I know that it's needed I need to load it ASAP and need to wait until it is loaded before I can perform the search. So: yes, I want to interrupt client operation completely while the code necessary to complete the search results happens. :p