Saving this here for future reference.
If you’re reading this, my guess is that you’re probably already familiar with jQuery’s awesome…
$('document').ready(function(){});
…for executing a function only after page load is complete.
But what if you’re working with plain old JavaScript and are either not allowed to, or just don’t want to use jQuery or any other JS library? If you have some function you want to execute only after the page has loaded and is ready to handle it, how do you ensure that the page has actually completely loaded?
Naturally, the fastest and purest approach would be to put the JavaScript code at the bottom of the HTML body tag (after the rest of the DOM has been processed). But assuming that’s just not possible for some reason, try one of the following 3 pure JavaScript alternatives to jQuery’s .ready() function:
Method 1: Great For Modern Browsers. Won’t Work For IE8 And Below.
Create this function:
function ehiPureJSReady(fn) { // Check if DOM is available yet if (document.readyState === "interactive" || document.readyState === "complete") { setTimeout(fn, 1); } else { // DOMContentLoaded works on modern browsers // But not on old ones like IE8 and below document.addEventListener("DOMContentLoaded", fn); } }
And Use It Like This:
ehiPureJSReady(function() { // The DOM is loaded. // You can now add your code to manipulate it here. });
The only 5 possible values of the readyState property (used in the above code) are: uninitialized, loading, loaded, interactive, and complete.
Method 2: Works Across All Browsers. But Feels A Little “Hacky”.
Create this function:
function ehiPureJSReady(fn) { /(?:loading|uninitialized)/.test(document.readyState) ? setTimeout('ehiPureJSReady(' + fn + ')',9) : fn(); }
And Use It Like This:
ehiPureJSReady(function(){ // The DOM is loaded. // You can now add your code to manipulate it here. });
What we’re doing here is that like in Method 1, we’re checking the readyState property of document. But this time, if it contains the string loading or uninitialized, we set a timeout and check again.
We keep doing this until readyState is NEITHER loading nor uninitialized. Then we execute the passed function.
Method 3: Works Across All Browsers. More Robust.
(function(funcName, baseObj) { "use strict"; funcName = funcName || "ehiPureJSReady"; baseObj = baseObj || window; var ehiReadyList = []; var isReadyFired = false; var isReadyEventHandlersInstalled = false; function ready() { if (!isReadyFired) { isReadyFired = true; for (var i = 0; i < ehiReadyList.length; i++) { ehiReadyList[i].fn.call(window, ehiReadyList[i].ctx); } ehiReadyList = []; } } function readyStateChange() { if ( document.readyState === "complete" ) { ready(); } } baseObj[funcName] = function(callback, context) { if (typeof callback !== "function") { throw new TypeError("callback for ehiPureJSReady(fn) must be a function"); } if (isReadyFired) { setTimeout(function() {callback(context);}, 1); return; } else { ehiReadyList.push({fn: callback, ctx: context}); } if (document.readyState === "complete" || (!document.attachEvent && document.readyState === "interactive")) { setTimeout(ready, 1); } else if (!isReadyEventHandlersInstalled) { if (document.addEventListener) { document.addEventListener("DOMContentLoaded", ready, false); window.addEventListener("load", ready, false); } else { document.attachEvent("onreadystatechange", readyStateChange); window.attachEvent("onload", ready); } isReadyEventHandlersInstalled = true; } } })("ehiPureJSReady", window);
You can use it in a number of different ways:
// Pass a named function to it ehiPureJSReady(fn);
// Pass an anonymous function ehiPureJSReady(function() { // The DOM is loaded. // You can now add your code to manipulate it here. });
// Pass a named function and a context. The context becomes the first argument of the function. ehiPureJSReady(fn, context);
// Pass an anonymous function and a context ehiPureJSReady(function(ctx) { // The DOM is loaded. // You can now add your code to manipulate it here. }, context);
For more information on Method 3 above, see here.
Have you used any of the above pure JavaScript alternatives to jQuery’s .ready() function? Please share your comments below.
Leave a Reply