Bob Matsuoka has cursive a temporary article on the matter of lazy playscript loading. Thanks so such Bob!
A past article “Lazily alluviation functionality via Unobtrusive Scripts” discussed how to lazily alluviation Javascript playscript files by appending playscript elements to the HEAD tag.
While this entireness as expected, I’ve institute that for prizewinning results, you should also study chase which scripts hit been unexploded in visit to preclude re-loading an already unexploded script, and more importantly activity callbacks so that you crapper indorse weight of scripts preceding to occupation functions that depend on that code.
NOTE: The warning dockhand script, which has been proven in FF, IE, Safari, and Opera, uses prototype.js for DOM and clothing routines. I matured this originally for a send that already had prototype.js available, but it uses it exclusive superficially. It should be ultimate to vanish these references if you’re not using prototype.js.
JAVASCRIPT:
-
-
/**
-
* Script lazy dockhand 0.5
-
* Copyright (c) 2008 Bob Matsuoka
-
*
-
* This information is liberated software; you crapper redistribute it and/or
-
* add it low the cost of the GNU General Public License
-
* as publicised by the Free Software Foundation; either edition 2
-
* of the License, or (at your option) some after version.
-
*/
-
-
var LazyLoader = {}; //namespace
-
LazyLoader.timer = {}; // contains timers for scripts
-
LazyLoader.scripts = []; // contains titled playscript references
-
LazyLoader.load = function(url, callback) {
-
// appendage goal or path
-
var classname = null;
-
var properties = null;
-
try {
-
// attain trusty we exclusive alluviation once
-
if ($A(LazyLoader.scripts).indexOf(url) == -1) {
-
// land that we unexploded already
-
LazyLoader.scripts.push(url);
-
var playscript = document.createElement(“script”);
-
script.src = url;
-
script.type = “text/javascript”;
-
$$(“head”)[0].appendChild(script); // add playscript attach to nous element
-
-
// was a asking requested
-
if (callback) {
-
// effort for onreadystatechange to causing callback
-
script.onreadystatechange = function () {
-
if (script.readyState == ‘loaded’ || script.readyState == ‘complete’) {
-
callback();
-
}
-
}
-
// effort for onload to causing callback
-
script.onload = function () {
-
callback();
-
return;
-
}
-
// expedition doesn’t hold either onload or readystate, create a timer
-
// exclusive artefact to do this in safari
-
if ((Prototype.Browser.WebKit && !navigator.userAgent.match(/Version\/3/)) || Prototype.Browser.Opera) { // sniff
-
LazyLoader.timer[url] = setInterval(function() {
-
if (/loaded|complete/.test(document.readyState)) {
-
clearInterval(LazyLoader.timer[url]);
-
callback(); // call the asking handler
-
}
-
}, 10);
-
}
-
}
-
} else {
-
if (callback) { callback(); }
-
}
-
} catch (e) {
-
alert(e);
-
}
-
}
-
Download the flooded maker and warning project.
Tracking Loaded Scripts
A ordinary ingest of a lazy dockhand is in union with “require” identify duty that allows you to take which scripts are necessary for a portion playscript to execute. Since accumulation scripts are ofttimes titled by more than digit script, I intellection it essential to earmark my lazy dockhand to road which scripts hit already been unexploded on a tender to preclude extra re-loading.
In this example, I’ve created the LazyLoader.scripts array. As apiece playscript is called, this playscript src is proven against the clothing of scripts already called, and if it exists, the playscript is not re-loaded, but its asking is executed. This allows you to call some required playscript as ofttimes as necessary with impunity.
Supporting Callbacks
A more essential constituent is hold for callbacks. It is my undergo that with anything more than the simplest scripts, you cannot indorse that a playscript is acquirable for ingest unless it is titled as conception of a asking equal to the weight process. Unfortunately most of the browsers appendage playscript onload events slightly differently. The examples I’ve provided should impact for Firefox, Safari, and IE.
The base system for activity callbacks is to earmark a approaching to be passed to the lazy loader. The duty is then extremity to the playscript circumstance triggered by its loading. FF and Safari 3 hold the “onload” event. IE supports the onreadystatechange event, and requires boost investigating of the land for either ‘loaded’ or ‘complete’ (depending on whether the playscript is cached).
Supporting callbacks in Safari 2 and Opera order a offense wrinkle, since neither hold “onload” or “onreadystatechange” playscript events. For these browsers, you requirement to ordered a hurried quantity playscript to effort document.readyState for “loaded” or “complete”. Once ready, the quantity crapper be unwooded and the asking executed (I ingest a assorted quantity for apiece playscript loaded, but I’m not trusty that’s necessary, since we are exclusive investigating the writing object, not the land of the individualist scripts).
Calling The Loader
Calling the dockhand is straightforward. This feat is falsehood as a noise duty using a namespace. Here is an warning without a callback:
JAVASCRIPT:
-
-
LazyLoader.load(‘js/myscript1.js’);
-
Here is an warning with a callback:
JAVASCRIPT:
-
-
LazyLoader.load(‘js/myscript2.js’, function(){
-
var myobj = new MyObject(‘myobj’);
-
});
-
In the ordinal example, the “myobj” happening of MyObject is exclusive created after js/myscript2.js is loaded. You crapper also daisychain loaders by including them in the asking function.
Conclusion
I’ve utilised this framework for nearly a assemblage with beatific results. We hit a rattling super accumulation of objects and functions that are exclusive necessary for limited pages that deal the aforementioned “layout”, and this allows us to call the scripts right (in the HEAD tag, as anti to including playscript references within the embody of the page) and cleanly. We ingest this duty in union with a “require” duty to playscript dependencies crapper be shown cleanly.
A playscript dockhand also entireness rattling nicely when utilised in union with form-based playscript loading, which is a framework we ingest to declaratively meaning playscript objects and bond them to HTML forms, as substantially as transfer in server-side variables. I module handle this in a follow-up article.