Permalink
/** | |
* JQuery Loader | |
* | |
* Help to async load jQuery and supporting inline javascript with calls like | |
* $(function(){}) | |
* or | |
* $(document).ready(function(){}) | |
* | |
* Include it, then just call : | |
* jQl.loadjQ('//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js'); | |
* | |
* You can also use it to load jQuery-dependent module in parallel, | |
* it will be queue and run after jQuery is loaded : | |
* jQl.loadjQ('//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js'); | |
* jQl.loadjQdep('my.example.com/js/myplugin.jquery.js'); | |
* | |
* If you use a defer inline script, you have to manually call boot() function : | |
* | |
* <script defer type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> | |
* <script type="text/javascript">jQl.boot();</script> | |
* | |
* | |
* | |
* jQuery will be loaded without blocking browser rendering, | |
* and during this all inline calls to $(document).ready() and $.getScript() | |
* will be queued. | |
* As soon as jQuery is ready, all queued ready() and getScript() calls will be run | |
* respecting their initial order | |
* | |
* Be careful : | |
* At the moment, inline call and getScript executions are not waiting jQuery-dependent modules, | |
* but only jQuery core | |
* However, when jQuery is loaded, jQuery-dependent modules already loaded | |
* are run before inline scripts. But if some modules are longer to load and arrive | |
* after jQuery, they will be run after queued inline calls | |
* | |
* v 1.2.0 | |
* (c) 2010-2013 Cedric Morin licence GPL | |
* | |
*/ | |
var jQl={ | |
/** | |
* the inline calls queue | |
*/ | |
"q":[], | |
/** | |
* the jQuery dependencies xhr loaded queue | |
*/ | |
"dq":[], | |
/** | |
* the jQuery.getScript queue | |
*/ | |
"gs":[], | |
/** | |
* the ready function that collect calls and put it in the queue | |
*/ | |
"ready":function(f){ | |
if(typeof f=='function'){ | |
jQl.q.push(f); | |
} | |
// return jQl in order to support jQuery(document).ready() | |
return jQl; | |
}, | |
"getScript":function(s,c){ | |
jQl.gs.push([s,c]); | |
}, | |
/** | |
* unqueue ready() function | |
* run all queues inline $.ready() calls | |
* in the right order and purge the queue | |
* | |
*/ | |
"unq":function(){ | |
for(var i=0;i<jQl.q.length;i++) | |
jQl.q[i](); | |
jQl.q=[];}, | |
/** | |
* unqueue getScript() function | |
* run all queues $.getScript calls | |
* in the right order and purge the queue | |
* | |
*/ | |
"ungs":function(){ | |
for(var i=0;i<jQl.gs.length;i++) | |
jQuery.getScript(jQl.gs[i][0],jQl.gs[i][1]); | |
jQl.gs=[]; | |
}, | |
/** | |
* boot function | |
* call it after calling jQuery in order to wait it's loaded | |
* or use it in onload='' on script defer/async element | |
* | |
* @param function callback | |
* a callback to call after jQuery is loaded | |
* | |
*/ | |
"bId":null, | |
"boot":function(callback){ | |
if(typeof window.jQuery.fn == 'undefined'){ | |
if (!jQl.bId) { | |
jQl.bId = setInterval(function(){jQl.boot(callback)},25); | |
} | |
return; | |
} | |
if (jQl.bId) { | |
clearInterval(jQl.bId); | |
} | |
jQl.bId=0; | |
// OK, jQuery is loaded, | |
// we can load additional jQuery dependents modules | |
jQl.unqjQdep(); | |
// then unqueue all getScript calls | |
jQl.ungs(); | |
// and last unqueue all inline calls | |
// (when document is ready) | |
jQuery(jQl.unq); | |
// call the callback if provided | |
if(typeof callback=='function') callback(); | |
}, | |
"booted":function(){return jQl.bId===0}, | |
/** | |
* load jQuery script asynchronously in all browsers | |
* by delayed dom injection | |
* @param string src | |
* jQuery url to use, can be a CDN hosted, | |
* or a compiled js including jQuery | |
* @param callback | |
*/ | |
"loadjQ":function(src,callback){ | |
setTimeout( | |
function(){ | |
var s=document.createElement('script'); | |
s.src=src; | |
document.getElementsByTagName('head')[0].appendChild(s) | |
}, | |
1); | |
jQl.boot(callback); | |
}, | |
/** | |
* | |
* | |
* | |
* jQuery-dependant modules loading | |
* this section is not necessary in case of loading only one script | |
* including jQuery | |
* Can be removed to make the booter smaller | |
* | |
* | |
* | |
* | |
* | |
* | |
*/ | |
/** | |
* load a jQuery-dependent script | |
* parallel loading in most browsers by xhr loading and injection | |
* the jQ-dependant script is queued or run when loaded, | |
* depending of jQuery loading state | |
*/ | |
"loadjQdep":function(src){ | |
jQl.loadxhr(src, jQl.qdep); | |
}, | |
/** | |
* queue jQuery-dependent script if download finish before jQuery loading | |
* or run it directly if jQuery loaded, and previous loaded modules are run | |
* (preserve initial order) | |
* | |
* @param string txt | |
* the js script to inject inline in dom | |
* @param string src | |
* the source url of the script, not used here | |
*/ | |
"qdep":function(txt, src){ | |
if (txt){ | |
if (typeof window.jQuery.fn!=="undefined" && !jQl.dq.length){ | |
jQl.rs(txt); | |
} | |
else { | |
jQl.dq.push(txt); | |
} | |
} | |
}, | |
/** | |
* dequeue jQuery-dependent modules loaded before jQuery | |
* call once only | |
*/ | |
"unqjQdep":function(){ | |
// security, should never happen | |
// so we keep setTimeout even if setInterval would be cleaner | |
if (typeof window.jQuery.fn=="undefined"){ | |
setTimeout(jQl.unqjQdep, 50); | |
return; | |
} | |
for (var i=0;i<jQl.dq.length;i++) jQl.rs(jQl.dq[i]); | |
jQl.dq = []; | |
}, | |
/** | |
* run a text script as inline js | |
* @param string txt | |
* js script | |
* @param string src | |
* original source of the script (not used here) | |
*/ | |
"rs":function(txt, src){ | |
var se = document.createElement('script'); | |
document.getElementsByTagName('head')[0].appendChild(se); | |
se.text = txt; | |
}, | |
/** | |
* multi-browsers XHr loader, | |
* credits http://www.stevesouders.com/blog/2009/04/27/loading-scripts-without-blocking/ | |
* | |
*/ | |
"loadxhr":function(src,callback) { | |
var xoe; | |
xoe = jQl.getxo(); | |
xoe.onreadystatechange = function() { | |
if ( xoe.readyState != 4 || 200 != xoe.status ) return; | |
callback(xoe.responseText,src); | |
}; | |
try { | |
xoe.open('GET', src, true); | |
xoe.send(''); | |
} | |
catch(e) { | |
} | |
}, | |
/** | |
* facilitie for XHr loader | |
* credits http://www.stevesouders.com/blog/2009/04/27/loading-scripts-without-blocking/ | |
* | |
*/ | |
"getxo":function (){ | |
var xhrObj = false; | |
try { | |
xhrObj = new XMLHttpRequest(); | |
} | |
catch(e){ | |
var progid = ['MSXML2.XMLHTTP.5.0', 'MSXML2.XMLHTTP.4.0', 'MSXML2.XMLHTTP.3.0', 'MSXML2.XMLHTTP', 'Microsoft.XMLHTTP']; | |
for ( var i=0; i < progid.length; ++i ) { | |
try { | |
xhrObj = new ActiveXObject(progid[i]); | |
} | |
catch(e){ | |
continue; | |
} | |
break; | |
} | |
} | |
finally { | |
return xhrObj; | |
} | |
} | |
}; | |
/** | |
* | |
* map $ and jQuery to the jQl.ready() function in order to catch all | |
* inline calls like : | |
* $(function(){...}) | |
* jQuery(function(){...}) | |
* $('document').ready(function(){...}) | |
* jQuery('document').ready(function(){...}) | |
* | |
* $.getScript() and jQuery.getScript() also catched and called | |
* | |
* only if jQuery is not already loaded | |
*/ | |
if (typeof window.jQuery=='undefined'){var $=jQl.ready,jQuery=$;$.getScript=jQl.getScript;} |