What is the non-jQuery equivalent of ‘$(document).ready()’?

What is the non-jQuery equivalent of ‘$(document).ready()’?

What is the non-jQuery equivalent of $(document).ready()?

Solutions/Answers:

Solution 1:

The nice thing about $(document).ready() is that it fires before window.onload. The load function waits until everything is loaded, including external assets and images. $(document).ready, however, fires when the DOM tree is complete and can be manipulated. If you want to acheive DOM ready, without jQuery, you might check into this library. Someone extracted just the ready part from jQuery. Its nice and small and you might find it useful:

domready at Google Code

Solution 2:

This works perfectly, from ECMA

document.addEventListener("DOMContentLoaded", function() {
  // code...
});

The window.onload doesn’t equal to JQuery $(document).ready because $(document).ready waits only to the DOM tree while window.onload check all elements including external assets and images.

EDIT: Added IE8 and older equivalent, thanks to Jan Derk‘s observation. You may read the source of this code on MDN at this link:

// alternative to DOMContentLoaded
document.onreadystatechange = function () {
    if (document.readyState == "interactive") {
        // Initialize your application or run some code.
    }
}

There are other options apart from "interactive". See the MDN link for details.

Solution 3:

A little thing I put together

domready.js

(function(exports, d) {
  function domReady(fn, context) {

    function onReady(event) {
      d.removeEventListener("DOMContentLoaded", onReady);
      fn.call(context || exports, event);
    }

    function onReadyIe(event) {
      if (d.readyState === "complete") {
        d.detachEvent("onreadystatechange", onReadyIe);
        fn.call(context || exports, event);
      }
    }

    d.addEventListener && d.addEventListener("DOMContentLoaded", onReady) ||
    d.attachEvent      && d.attachEvent("onreadystatechange", onReadyIe);
  }

  exports.domReady = domReady;
})(window, document);

How to use it

<script src="domready.js"></script>
<script>
  domReady(function(event) {
    alert("dom is ready!");
  });
</script>

You can also change the context in which the callback runs by passing a second argument

function init(event) {
  alert("check the console");
  this.log(event);
}

domReady(init, console);

Solution 4:

There is a standards based replacement,DOMContentLoaded that is supported by over 90%+ of browsers, but not IE8 (So below code use by JQuery for browser support):

document.addEventListener("DOMContentLoaded", function(event) { 
  //do work
});

jQuery’s native function is much more complicated than just window.onload, as depicted below.

function bindReady(){
    if ( readyBound ) return;
    readyBound = true;

    // Mozilla, Opera and webkit nightlies currently support this event
    if ( document.addEventListener ) {
        // Use the handy event callback
        document.addEventListener( "DOMContentLoaded", function(){
            document.removeEventListener( "DOMContentLoaded", arguments.callee, false );
            jQuery.ready();
        }, 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", function(){
            if ( document.readyState === "complete" ) {
                document.detachEvent( "onreadystatechange", arguments.callee );
                jQuery.ready();
            }
        });

        // If IE and not an iframe
        // continually check to see if the document is ready
        if ( document.documentElement.doScroll && window == window.top ) (function(){
            if ( jQuery.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( arguments.callee, 0 );
                return;
            }

            // and execute any waiting functions
            jQuery.ready();
        })();
    }

    // A fallback to window.onload, that will always work
    jQuery.event.add( window, "load", jQuery.ready );
}

Solution 5:

Now that it’s 2018 here’s a quick and simple method.

This will add an event listener, but if it already fired we’ll check that the dom is in a ready state or that it’s complete. This can fire before or after sub-resources have finished loading (images, stylesheets, frames, etc).

function domReady(fn) {
  // If we're early to the party
  document.addEventListener("DOMContentLoaded", fn);
  // If late; I mean on time.
  if (document.readyState === "interactive" || document.readyState === "complete" ) {
    fn();
  }
}

domReady(() => console.log("DOM is ready, come and get it!"));

Additional Readings


Update

Here’s some quick utility helpers using standard ES6 Import & Export I wrote that include TypeScript as well. Maybe I can get around to making these a quick library that can be installed into projects as a dependency.

JavaScript

export const domReady = (callBack) => {
  if (document.readyState === "loading") {
    document.addEventListener('DOMContentLoaded', callBack);
  }
  else {
    callBack();
  }
}

export const windowReady = (callBack) => {
  if (document.readyState === 'complete') {
    callBack();
  }
  else {
    window.addEventListener('load', callBack);
  }
}

TypeScript

export const domReady = (callBack: () => void) => {
  if (document.readyState === "loading") {
    document.addEventListener('DOMContentLoaded', callBack);
  }
  else {
    callBack();
  }
}

export const windowReady = (callBack: () => void) => {
  if (document.readyState === 'complete') {
    callBack();
  }
  else {
    window.addEventListener('load', callBack);
  }
}

Promises

export const domReady = new Promise(resolve => {
  if (document.readyState === "loading") {
    document.addEventListener('DOMContentLoaded', resolve);
  }
  else {
    resolve();
  }
});

export const windowReady = new Promise(resolve => {
  if (document.readyState === 'complete') {
    resolve();
  }
  else {
    window.addEventListener('load', resolve);
  }
});

Solution 6:

According to http://youmightnotneedjquery.com/#ready a nice replacement that still works with IE8 is

function ready(fn) {
  if (document.readyState != 'loading') {
    fn();
  } else if (document.addEventListener) {
    document.addEventListener('DOMContentLoaded', fn);
  } else {
    document.attachEvent('onreadystatechange', function() {
      if (document.readyState != 'loading')
        fn();
    });
  }
}

// test
window.ready(function() {
    alert('it works');
});

Personally I would also check if the type of fn is a function.

The reason I answer this question late is because I was searching for this answer but could not find it here. And I think this is the best solution.