public
Last active

documentReady

  • Download Gist
documentReady.js
JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
/*
* documentReady.js - a cross-browser jQuery core based DOMContentLoaded solution
* Released under an MIT license
* Portions: jQuery project, Diego Perini, Lucent M.
* This version: Addy Osmani, 2012
*/
 
/*
* Usage:
documentReady(function(){
...
});
*/
 
;(function( window, document, undefined ) {
 
var documentReady = function( callback ){
readyBound = false;
documentReady.isReady = false;
if( typeof callback == 'function' ){
DOMReadyCallback = callback;
}
bindReady();
},
 
// Use the correct document accordingly with window argument (sandbox)
document = window.document,
 
readyBound = false,
 
DOMReadyCallback = function(){},
 
// The ready event handler
DOMContentLoaded;
 
// Is the DOM ready to be used? Set to true once it occurs.
documentReady.isReady = false;
 
// Handle when the DOM is ready
var DOMReady = function() {
// Make sure that the DOM is not already loaded
if ( !documentReady.isReady ) {
// Make sure body exists, at least, in case IE
// gets a little overzealous (ticket #5443).
if ( !document.body ) {
setTimeout( DOMReady, 13 );
return;
}
 
// Remember that the DOM is ready
documentReady.isReady = true;
 
// If there are functions bound, to execute
DOMReadyCallback();
// Execute all of them
}
}// /ready()
 
var bindReady = function() {
if ( readyBound ) {
return;
}
 
readyBound = true;
 
// Catch cases where documentReady is called after the
// browser event has already occurred.
if ( document.readyState === "complete" ) {
DOMReady();
}
 
// Mozilla, Opera and webkit support this event
if ( document.addEventListener ) {
// Use the handy event callback
document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
 
// A fallback to window.onload, that will always work
window.addEventListener( "load", DOMContentLoaded, false );
 
// If IE event model is used
}
else if ( document.attachEvent ) {
// ensure firing before onload,
// maybe late but safe also for iframes
document.attachEvent("onreadystatechange", DOMContentLoaded);
 
// A fallback to window.onload, that will always work
window.attachEvent( "onload", DOMContentLoaded );
 
// If IE and not a frame
// continually check to see if the document is ready
var toplevel = false;
 
try {
toplevel = window.frameElement == null;
} catch(e) {}
 
if ( document.documentElement.doScroll && toplevel ) {
doScrollCheck();
}
}
};// /bindReady()
 
// The DOM ready check for Internet Explorer
var doScrollCheck = function() {
if ( documentReady.isReady ) {
return;
}
 
try {
// If IE is used, use the trick by Diego Perini
// http://javascript.nwbox.com/IEContentLoaded/
document.documentElement.doScroll("left");
} catch( error ) {
setTimeout( doScrollCheck, 1 );
return;
}
// and execute any waiting functions
DOMReady();
}// /doScrollCheck()
 
// Cleanup functions for the document ready method
if ( document.addEventListener ) {
DOMContentLoaded = function() {
document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
DOMReady();
};
 
}
else if ( document.attachEvent ) {
DOMContentLoaded = function() {
// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
if ( document.readyState === "complete" ) {
document.detachEvent( "onreadystatechange", DOMContentLoaded );
DOMReady();
}
};
}
 
// Expose documentReady to the global object
window.documentReady = documentReady;
})(window);

Sample usage: http://jsfiddle.net/fEGgD/1/

Currently tested: Chrome (stable, canary), Safari, FF, Opera. Will test in IE shortly.

@jdalton sure this has been written/solved elsewhere a million times over, but if there are any changes/suggestions you would make on the above, always happy to hear them. Had to put something like this together for a non-jq project recently.

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.