Skip to content

Instantly share code, notes, and snippets.

@addyosmani
Created January 8, 2012 23:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save addyosmani/1580191 to your computer and use it in GitHub Desktop.
Save addyosmani/1580191 to your computer and use it in GitHub Desktop.
documentReady
/*
* 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);
//872 bytes
(function(a,b,c){var d=function(a){e=!1,d.isReady=!1,typeof a=="function"&&(f=a),i()},b=a.document,e=!1,f=function(){},g;d.isReady=!1;var h=function(){if(!d.isReady){if(!b.body){setTimeout(h,13);return}d.isReady=!0,f()}},i=function(){if(e)return;e=!0,b.readyState==="complete"&&h();if(b.addEventListener)b.addEventListener("DOMContentLoaded",g,!1),a.addEventListener("load",g,!1);else if(b.attachEvent){b.attachEvent("onreadystatechange",g),a.attachEvent("onload",g);var c=!1;try{c=a.frameElement==null}catch(d){}b.documentElement.doScroll&&c&&j()}},j=function(){if(d.isReady)return;try{b.documentElement.doScroll("left")}catch(a){setTimeout(j,1);return}h()};b.addEventListener?g=function(){b.removeEventListener("DOMContentLoaded",g,!1),h()}:b.attachEvent&&(g=function(){b.readyState==="complete"&&(b.detachEvent("onreadystatechange",g),h())}),a.documentReady=d})(window)
@addyosmani
Copy link
Author

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

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

@addyosmani
Copy link
Author

@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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment