Dynamically load javascript with load completion notification

Here's a javascript function to dynamically load javascript into a page and get a notification (callback) when the script is done loading.

I used to use the good 'ol window.onload handler - but I've found that this way is better as the Web APIs we're building need to dynamically add scripts to the page that is embedding them and know when the script is done loading!

The main advantage :
This function loads the specified script and calls the javascript function you specify when the script has finished loading.
Your code can call this at any time during the life of your app - even based on user interaction! (see HTML test code below below).

This "lazy script loading" has other advantages:
- reducing the initial page / app load time
- allows for loading scripts based on user input / feature requirements


The add_script function



/* utility to add a script node to the current document
and call the callback function when it is loaded.
Should allow scripts to be loaded at any time during document
life..and have code be kicked off after they are loaded.

Browsers tested:
FF 3.6.x - WORKS
Chrome 5.x - WORKS
Safari 4.x - WORKS
MS IE 8 - WORKS
Opera 10.x - WORKS
*/

function add_script(scriptURL, onloadCB) {
var scriptEl = document.createElement("script");
scriptEl.type = "text/javascript";
scriptEl.src = scriptURL;

function calltheCBcmn() {
onloadCB(scriptURL);
}

if(typeof(scriptEl.addEventListener) != 'undefined') {
/* The FF, Chrome, Safari, Opera way */
scriptEl.addEventListener('load',calltheCBcmn,false);
}
else {
/* The MS IE 8+ way (may work with others - I dunno)*/
function handleIeState() {
if(scriptEl.readyState == 'loaded'){
calltheCBcmn(scriptURL);
}
}
var ret = scriptEl.attachEvent('onreadystatechange',handleIeState);
}
document.getElementsByTagName("head")[0].appendChild(scriptEl);
}





The HTML used to test loading two scripts based on user input




<!DOCTYPE HTML>
<html>
<head>
<TITLE> Script load testing</TITLE>
</head>
<body>

<div id="control_area" style="width:100%;height:100%;border:solid red 1px">
Select the script to load:
<select id="script_selector" size="1">
<option> ./gen_include2.js</option>
<option> ./gen_include.js</option>
</select>
<ul>
<li> <a href="javascript:void(0);" onclick="load_selected();"> Load selected script</a> </li>
</ul>
</div>
<div id="output_area"
style="position:relative;width:100%;height:200px;overflow:auto;
border: dotted 1px #ff0000;">
</div>

<script type="text/javascript">

/* clear the scratch area */
document.getElementById("output_area").value = "";

function load_selected() {
output_str("+load_selected");
var ssel = document.getElementById("script_selector");
var sselURL = ssel.options[parseInt(ssel.selectedIndex)].text;

function myOnloadCB(loadedScriptURL) {
output_str("myOnloadCB,script loaded: " + loadedScriptURL);
if(typeof(window.gen_include_js) != 'undefined'){
output_str("window.gen_include_js exists in DOM");
}
if(typeof(window.gen_include_js2) != 'undefined'){
output_str("window.gen_include_js2 exists in DOM");
}
}
add_script(sselURL, myOnloadCB);
}

/* utility to add a script node to the current document
and call the callback function when it is loaded.
Should allow scripts to be loaded at any time during document
life..and have code be kicked off after they are loaded.

Browsers tested:
FF 3.6.x - WORKS
Chrome 5.x - WORKS
Safari 4.x - WORKS
MS IE 8 - WORKS
Opera 10.x - WORKS
*/
function add_script(scriptURL, onloadCB) {
output_str("+add_script");
var scriptEl = document.createElement("script");
scriptEl.type = "text/javascript";
scriptEl.src = scriptURL;

function calltheCBcmn() {
onloadCB(scriptURL);
}

if(typeof(scriptEl.addEventListener) != 'undefined') {
/* FF, Chrome, Safari way */
scriptEl.addEventListener('load',calltheCBcmn,false);
}
else {
/* MS IE way */
function handleIeState() {
output_str("+handleIeState,scriptEl.readyState=" + scriptEl.readyState);
if(scriptEl.readyState == 'loaded'){
calltheCBcmn(scriptURL);
}
}
var ret = scriptEl.attachEvent('onreadystatechange',handleIeState);
output_str("attachEvent ret = " + ret);
}
document.getElementsByTagName("head")[0].appendChild(scriptEl);
}

/* function to print to the the output_area div */
function output_str(str){
var da = document.getElementById("output_area");
da.innerHTML += str + "<br/> ";
da.scrollTop = da.scrollHeight;
}
</script>

</body>
</html>






The contents of the 2 .js files dynamically loaded in the HTML above.



/* gen_include.js */
(function()
{
window.gen_include_js = {};
window.gen_include_js.loaded = true;
}
)();


/* gen_include2.js */
(function()
{
window.gen_include_js2 = {};
window.gen_include_js2.loaded = true;
}
)();

Per informazioni più dettagliate sulle ottimizzazioni basate su compilatore, vedere il nostro Avviso sull'ottimizzazione.
Contrassegni: