NeuroAgent

Complete jQuery Ready Alternative

Replace jQuery's document.ready() with native JavaScript methods. Explore DOMContentLoaded, readyState checks, and cross-browser solutions for modern and legacy browsers.

Question

Vanilla JavaScript equivalent of jQuery’s $.ready() - how to call a function when the page/DOM is ready for it

With jQuery, we all know the wonderful .ready() function:

javascript
$('document').ready(function(){});

However, let’s say I want to run a function that is written in standard JavaScript with no library backing it, and that I want to launch a function as soon as the page is ready to handle it. What’s the proper way to approach this?

I know I can do:

javascript
window.onload="myFunction()";

Or I can use the body tag:

html
<body onload="myFunction()">

Or I can even try at the bottom of the page after everything, but the end body or html tag like:

html
<script type="text/javascript">
    myFunction();
</script>

What is a cross-browser(old/new)-compliant method of issuing one or more functions in a manner like jQuery’s $.ready()?

NeuroAgent

The vanilla JavaScript equivalent of jQuery’s $.ready() is primarily the DOMContentLoaded event, which fires when the initial HTML document has been completely loaded and parsed, without waiting for stylesheets, images, and subframes to finish loading. For cross-browser compatibility including older Internet Explorer versions, you’ll need to implement a more comprehensive solution that checks the document’s ready state and uses appropriate event listeners for different browsers.

Contents

Modern Browser Solution

The most straightforward approach for modern browsers is to use the DOMContentLoaded event:

javascript
document.addEventListener("DOMContentLoaded", function() {
    // Your code here
    console.log("DOM is ready!");
});

This is the direct equivalent of jQuery’s $(document).ready() and works in all modern browsers including Chrome, Firefox, Safari, and IE9+ [source]. The event fires when the DOM is fully loaded but before images and other external resources have finished loading, making it faster than window.onload.

Cross-Browser Implementation

For full cross-browser compatibility including older versions of Internet Explorer, you need a more robust solution. Here’s a comprehensive implementation that handles all browsers from IE6 and up:

javascript
function docReady(fn) {
    // Check if DOM is already available
    if (document.readyState === "complete" || document.readyState === "interactive") {
        // Call on next available tick
        setTimeout(fn, 1);
    } else {
        // Use DOMContentLoaded for modern browsers
        document.addEventListener("DOMContentLoaded", fn);
    }
}

// Usage
docReady(function() {
    // Your code here
    console.log("DOM is ready!");
});

For even broader compatibility including IE8 and below, here’s an enhanced version:

javascript
function ready(fn) {
    // Check if DOM is already loaded
    if (document.readyState !== 'loading') {
        fn();
    } else if (document.addEventListener) {
        // For modern browsers
        document.addEventListener('DOMContentLoaded', fn);
    } else {
        // For IE8 and below
        document.attachEvent('onreadystatechange', function() {
            if (document.readyState === 'complete') {
                fn();
            }
        });
    }
}

// Usage
ready(function() {
    // Your code here
    console.log("DOM is ready!");
});

This implementation handles the different ways browsers signal that the DOM is ready, working across all major browsers including IE6+ [source]. According to Raymon Schouwenaar’s cross-browser solution, this approach covers all browser versions.

Alternative Approaches

Check Document Ready State Directly

You can check the document’s ready state without using events:

javascript
function domReady(callback) {
    if (document.readyState === "interactive" || document.readyState === "complete") {
        callback();
    } else {
        document.addEventListener("DOMContentLoaded", callback);
    }
}

domReady(function() {
    // Your code here
});

This method, as explained by Beeker.io, checks the current state and either executes immediately or waits for the event.

Script with Defer Attribute

Simply add the defer attribute to your script tag:

html
<script src="your-script.js" defer></script>

The defer attribute tells the browser to download the script without blocking HTML parsing and execute it after the document has been parsed but before DOMContentLoaded [source]. As mentioned in the Reddit discussion, this is a modern alternative to jQuery’s ready function.

Script at Bottom of Body

Place your script tag just before the closing </body> tag:

html
<!DOCTYPE html>
<html>
<head>
    <title>Page Title</title>
</head>
<body>
    <!-- Your content here -->
    
    <script>
        // Your code here
        console.log("DOM is ready!");
    </script>
</body>
</html>

This is the simplest approach and works reliably in all browsers, though it’s not as flexible as the event-based solutions [source].

Browser Compatibility

Here’s a compatibility overview for different approaches:

Method IE6-8 IE9+ Chrome Firefox Safari Opera
DOMContentLoaded
onreadystatechange
document.readyState
Script placement
Defer attribute

The DOMContentLoaded event is supported by over 98% of browsers but not IE8 and below [source]. For complete compatibility, you need to combine multiple approaches as shown in the cross-browser implementation.

For most projects today, I recommend this cross-browser ready function:

javascript
function domReady(callback) {
    // If DOM is already loaded, execute callback
    if (document.readyState === 'interactive' || document.readyState === 'complete') {
        callback();
    } else {
        // For modern browsers
        document.addEventListener('DOMContentLoaded', callback);
        
        // For IE8 and below
        if (document.attachEvent) {
            document.attachEvent('onreadystatechange', function() {
                if (document.readyState === 'complete') {
                    callback();
                }
            });
        }
    }
}

// Usage
domReady(function() {
    // Multiple functions can be added
    initializeComponents();
    setupEventListeners();
    loadDynamicContent();
});

// Or create a namespace for multiple functions
var DOMReady = {
    callbacks: [],
    
    add: function(callback) {
        if (document.readyState === 'interactive' || document.readyState === 'complete') {
            callback();
        } else {
            this.callbacks.push(callback);
        }
    },
    
    ready: function() {
        var callbacks = this.callbacks;
        for (var i = 0; i < callbacks.length; i++) {
            callbacks[i]();
        }
    }
};

// Add your functions
DOMReady.add(function() {
    console.log("First function ready");
});

DOMReady.add(function() {
    console.log("Second function ready");
});

// Initialize when DOM is ready
domReady(DOMReady.ready);

This solution provides:

  • Full cross-browser compatibility (IE6+)
  • Support for multiple callback functions
  • Immediate execution if DOM is already ready
  • Clean, reusable code structure

According to the CSS-Tricks article, this approach works effectively across all browsers while maintaining clean, dependency-free code.


Sources

  1. Stack Overflow - Vanilla JavaScript equivalent of jQuery’s $.ready()
  2. GitHub - vanilla-ready
  3. Reddit - What should I use instead of jQuery’s $(document).ready()?
  4. Stack Overflow - What is the non-jQuery equivalent of ‘$(document).ready()’?
  5. Raymon Schouwenaar - Cross-browser Document Ready with Vanilla JavaScript
  6. Beeker.io - jQuery $(document).ready() Equivalent in Vanilla JavaScript
  7. CSS-Tricks - Cross-Browser Dependency-Free DOM Ready
  8. Wikitechy - $(document).ready equivalent without jQuery
  9. WPShout - jQuery document.ready in Vanilla JavaScript
  10. SitePoint - Replace the jQuery Document Ready Function with JavaScript

Conclusion

The vanilla JavaScript equivalent of jQuery’s $.ready() can be implemented using several approaches depending on your browser compatibility requirements:

  1. For modern browsers: Use document.addEventListener("DOMContentLoaded", callback) - this is the cleanest and most straightforward solution
  2. For full cross-browser compatibility: Implement a function that checks document.readyState and uses both addEventListener and attachEvent for older IE versions
  3. For simplicity: Place scripts at the end of the body or use the defer attribute
  4. For multiple functions: Create a ready function that maintains an array of callbacks

The recommended approach combines modern event handling with legacy support, ensuring your code works across all browsers from IE6 to the latest versions. This solution maintains the same behavior as jQuery’s ready function while being lightweight and dependency-free.

Remember that while window.onload works, it waits for all resources (images, stylesheets, etc.) to load, whereas DOM-ready fires as soon as the HTML structure is available, making it faster and more similar to jQuery’s behavior.