Skip to content

Instantly share code, notes, and snippets.

@jourdein
Last active November 1, 2015 18:07
Show Gist options
  • Save jourdein/fc307ab2fd76cb44d779 to your computer and use it in GitHub Desktop.
Save jourdein/fc307ab2fd76cb44d779 to your computer and use it in GitHub Desktop.
Defer loading js files companion script. Upon successfully parsed js files, re-run any function that has been attached to jquery ready function.
/**
* Was based on code: https://gist.github.com/miguel-perez/476046a42d229251fec3
*
* Replace jQuery's $.fn.ready() function with a mod exec
*
* Sites that make heavy use of the $(document).ready function
* are generally incompatible with asynchronous content.
*
*
* This script replaces the ready function with a
* module execution controller that
* 1. register function sent to __$.fn.ready__
* 2. keep track of the js files that will be loaded async
* and execute all of the functions when all the js files
* have been downloaded.
*
* This avoid any dependency that might have between those files.
*
* @author Jourdein
* @note Should be placed directly after jQuery on the page
* @date 2 November 2015
*/
(function($){
var $doc = $(document);
/** create mod exec controller */
$.readyFn = {
libs: [],
list: [],
register: function(fn) {
$.readyFn.list.push(fn);
},
isHandlerRegistered: function( handler ) {
var isRegister = false;
$.each($.readyFn.list, function(k, v) {
if (v === handler) {
isRegister = true;
return false;
}
});
return isRegister;
},
registerLib: function( lib ) {
lib.onload = function() {
libEl = this;
// console.log('onloaded', this.src.substring(0, this.src.lastIndexOf('-')))
$.readyFn.libs = $.readyFn.libs.filter( function (e) {
return e != libEl;
});
data = jQuery.hasData($(document)[0]) && jQuery._data($(document)[0])
if (data) {
if (data.events['ready']) {
if (!$.readyFn.isHandlerRegistered( data.events['ready'][0].handler )) {
$.readyFn.register(data.events['ready'][0].handler)
}
}
}
if ( $.readyFn.libs.length == 0 ) {
$.readyFn.execute();
/*
Triggering 'load' event is wrapped in setTimeout.
I think, this to make sure the function/library succesfully initialize.
Some initialization involve binding to 'load' event. If the library wasn't yet bounded to the event,
the trigger won't do anything.
*/
setTimeout(function() {
//console.log('onLoad(readyState): %c %s %c %s ', 'background: #222; color: #bada55', document.readyState, 'background: #6fc; color: #4c4c4c', "☞ triggering window.load() ")
$(window).trigger('load')
},1000)
}
}
$.readyFn.libs.push( lib );
},
execute: function() {
for (var i = 0; i < $.readyFn.list.length; i++) {
//console.log(i)
try {
//console.log( '('+$.readyFn.list.length+'/'+i+')executing ', $.readyFn.list[i])
$.readyFn.list[i].apply(document, [$])
}
catch (e) {
throw e;
}
};
}
};
/** run all functions */
$doc.ready(function(){
$.readyFn.execute();
});
/** register function */
$.fn.ready = function( fn ) {
$.readyFn.register(fn);
// preserve default behaviour
// $.ready.promise().done( fn );
};
})(jQuery);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment