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

Viewed 321738

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

9 Answers

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);
  }
});

This does not answer the question nor does it show any non-jQuery code. See @ sospedra's answer below.

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

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');
});

improvements: Personally I would also check if the type of fn is a function. And as @elliottregan suggested remove the event listener after use.

function ready(fn) {
  if (typeof fn !== 'function') {
    throw new Error('Argument passed to ready should be a function');
  }

  if (document.readyState != 'loading') {
    fn();
  } else if (document.addEventListener) {
    document.addEventListener('DOMContentLoaded', fn, {
      once: true // A boolean value indicating that the listener should be invoked at most once after being added. If true, the listener would be automatically removed when invoked.
    });
  } else {
    document.attachEvent('onreadystatechange', function() {
      if (document.readyState != 'loading')
        fn();
    });
  }
}

// tests
try {
  window.ready(5);
} catch (ex) {
  console.log(ex.message);
}


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

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.

In plain vanilla JavaScript, with no libraries? It's an error. $ is simply an identifier, and is undefined unless you define it.

jQuery defines $ as it's own "everything object" (also known as jQuery so you can use it without conflicting with other libraries). If you're not using jQuery (or some other library that defines it), then $ will not be defined.

Or are you asking what the equivalent is in plain JavaScript? In that case, you probably want window.onload, which isn't exactly equivalent, but is the quickest and easiest way to get close to the same effect in vanilla JavaScript.

Related