Web

Vanilla JavaScript DOMContentLoaded: Document Ready Equivalent

Learn the vanilla JavaScript equivalent of jQuery's $(document).ready() using DOMContentLoaded event. Execute code after DOM is fully loaded without jQuery.

1 answer 1 view

What is the non-jQuery equivalent of $(document).ready() in vanilla JavaScript? How can I execute code after the DOM is fully loaded without using jQuery?

The vanilla JavaScript equivalent of jQuery’s $(document).ready() is the DOMContentLoaded event. You can execute code after the DOM is fully loaded by using document.addEventListener("DOMContentLoaded", function() { // your code here }) or by placing your script tags at the bottom of the HTML body for immediate execution.


Contents


Understanding jQuery’s $(document).ready()

jQuery’s $(document).ready() function is one of the most commonly used methods in jQuery development. It allows you to execute code only after the HTML document has been fully loaded and parsed, but before external resources like images, stylesheets, and iframes are completely loaded. This ensures that your JavaScript can safely manipulate the DOM without errors.

The ready() function is particularly useful because it solves the timing problem that developers face when working with JavaScript - you need to ensure that the DOM elements you’re trying to manipulate actually exist before your code attempts to access them. Without proper DOM ready detection, your code might run before the HTML is fully parsed, resulting in elements not being found and JavaScript errors.

In jQuery, you can use $(document).ready() in several ways:

javascript
// Standard syntax
$(document).ready(function() {
 // Code here
});

// Shorthand version
$(function() {
 // Code here
});

The ready() function is powerful because it can be called multiple times without overwriting previous handlers, and it ensures that all handlers are executed in the order they were added.


The Primary Vanilla JavaScript Equivalent: DOMContentLoaded

The most direct and recommended vanilla JavaScript equivalent to jQuery’s $(document).ready() is the DOMContentLoaded event. This event fires when the initial HTML document has been completely loaded and parsed, without waiting for stylesheets, images, and subframes to finish loading.

To use DOMContentLoaded, you add an event listener to the document object:

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

This approach provides the same functionality as jQuery’s ready() method - it ensures your code runs only after the DOM structure is available. The DOMContentLoaded event has several advantages over alternatives like the window.onload event:

  1. Performance: DOMContentLoaded fires much earlier than window.onload because it doesn’t wait for external resources
  2. Flexibility: You can add multiple event listeners that will all execute in the order they were added
  3. Standardization: It’s a standard DOM event that’s supported by all modern browsers

Here’s how you might implement it in practice:

javascript
// Basic implementation
document.addEventListener("DOMContentLoaded", function() {
 console.log('DOM fully loaded and parsed');
 // Initialize your application
 initApp();
});

// With named function for better code organization
function initApp() {
 // Find elements
 const button = document.getElementById('myButton');
 const container = document.querySelector('.container');
 
 // Add event listeners
 button.addEventListener('click', handleClick);
 
 // Perform other DOM operations
 container.classList.add('initialized');
}

function handleClick(event) {
 // Handle button clicks
 console.log('Button clicked!');
}

The DOMContentLoaded event is the preferred method for modern web development when you need to execute code as soon as the DOM is ready, without the overhead of jQuery.


Alternative Methods for DOM Ready Detection

While DOMContentLoaded is the primary equivalent to jQuery’s ready() function, there are several alternative approaches you can use depending on your specific needs and browser compatibility requirements. Each method has its own advantages and use cases.

1. Window Load Event

The window load event fires when the entire page, including all dependent resources like images and stylesheets, has finished loading. This is different from DOMContentLoaded because it waits for everything to be ready.

javascript
window.addEventListener('load', function() {
 // This code runs after everything is loaded
 console.log('Page fully loaded');
});

Use this when you need to work with dimensions of images or iframes, or when you need to ensure all styles are applied before executing your JavaScript.

2. Script Placement at Bottom of Body

One of the simplest approaches is to place your script tags at the end of the HTML body, just before the closing </body> tag. This ensures that all HTML elements are parsed before your script runs.

html
<!DOCTYPE html>
<html>
<head>
 <title>My Page</title>
</head>
<body>
 <!-- All HTML content goes here -->
 
 <script>
 // This code runs after DOM is ready
 console.log('DOM is ready');
 // Direct DOM manipulation works here
 const element = document.getElementById('myElement');
 </script>
 
</body>
</html>

This method has the advantage of requiring no additional JavaScript code to check for DOM readiness.

3. Defer Attribute

The defer attribute tells the browser to download the script while parsing the HTML, but to execute it only after the document has been parsed.

html
<script src="app.js" defer></script>

Scripts with the defer attribute execute in the order they appear in the document, and they have access to the full DOM. This is particularly useful when you have multiple scripts that depend on each other.

4. Async Attribute

While not exactly equivalent to ready(), the async attribute is worth mentioning as it affects script loading:

html
<script src="analytics.js" async></script>

Async scripts load asynchronously and execute as soon as they’re downloaded, which might be before or after DOM parsing. Use async for scripts that don’t need to interact with the DOM immediately.

5. IE9+ Polyfill for DOMContentLoaded

For older browser support, you can implement a simple polyfill for DOMContentLoaded:

javascript
// Check if DOMContentLoaded is supported
if (document.addEventListener) {
 // Modern browsers
 document.addEventListener('DOMContentLoaded', function() {
 console.log('DOM is ready');
 });
} else {
 // Older IE versions
 document.attachEvent('onreadystatechange', function() {
 if (document.readyState === 'complete') {
 console.log('DOM is ready');
 }
 });
}

Each of these methods provides a different approach to determining when it’s safe to manipulate the DOM. The best choice depends on your specific requirements and the browsers you need to support.


Browser Compatibility Considerations

When implementing DOM ready detection in vanilla JavaScript, it’s important to consider browser compatibility, especially if you need to support older browsers or Internet Explorer. While DOMContentLoaded is widely supported, there are some differences in implementation across browsers that you should be aware of.

Modern Browser Support

The DOMContentLoaded event is supported in all modern browsers:

  • Chrome 1.0+
  • Firefox 1.0+
  • Safari 3.1+
  • Opera 9.0+
  • Edge 12+

For these browsers, you can safely use document.addEventListener("DOMContentLoaded", callback) without any special considerations.

Internet Explorer Support

Internet Explorer has some quirks that you should be aware of:

  1. IE8 and below: These versions don’t support DOMContentLoaded. For these browsers, you need to use a different approach.

  2. IE9+: Supports DOMContentLoaded but has some timing differences compared to other browsers.

Here’s a compatibility solution that handles different browser versions:

javascript
// Cross-browser DOM ready implementation
function domReady(callback) {
 // Modern browsers
 if (document.addEventListener) {
 document.addEventListener('DOMContentLoaded', callback);
 } 
 // IE8 and below
 else {
 // Make sure body exists
 if (document.body) {
 // Call callback
 callback();
 } else {
 // Wait for body to be created
 setTimeout(domReady(callback), 100);
 }
 }
}
 
// Usage
domReady(function() {
 console.log('DOM is ready across all browsers');
 // Your initialization code here
});

Performance Considerations

Different DOM ready methods have different performance implications:

  1. DOMContentLoaded: Fires as soon as the DOM is ready, before external resources finish loading
  2. Window load: Fires after everything is loaded, which can significantly delay execution
  3. Script at bottom: Executes after HTML parsing but before external resources finish loading
  4. Defer scripts: Execute after DOM parsing but may execute out of order if multiple scripts are used

For optimal performance, prefer DOMContentLoaded or script placement at the bottom of the body, depending on your project structure.

Feature Detection vs. Browser Detection

Instead of checking specific browser versions, it’s better to use feature detection:

javascript
// Feature detection approach
if (document.addEventListener) {
 // Modern browser
 document.addEventListener('DOMContentLoaded', init);
} else if (document.attachEvent) {
 // Older IE
 document.attachEvent('onreadystatechange', function() {
 if (document.readyState === 'complete') {
 init();
 }
 });
} else {
 // Fallback - just run the function
 init();
}
 
function init() {
 // Your initialization code
}

This approach is more maintainable than checking specific browser versions, as it will work with any browser that supports the appropriate feature, regardless of its version number.


Best Practices and Implementation Examples

Implementing DOM ready detection properly is crucial for robust web applications. Here are some best practices and practical examples to help you execute code after the DOM is fully loaded using vanilla JavaScript.

1. Modular Approach with IIFE

For better code organization and to avoid polluting the global namespace, wrap your DOM ready code in an Immediately Invoked Function Expression (IIFE):

javascript
(function() {
 'use strict';
 
 // DOM ready implementation
 function domReady(callback) {
 if (document.readyState === 'interactive' || document.readyState === 'complete') {
 setTimeout(callback, 1);
 } else if (document.addEventListener) {
 document.addEventListener('DOMContentLoaded', callback);
 } else {
 document.attachEvent('onreadystatechange', function() {
 if (document.readyState === 'complete') {
 callback();
 }
 });
 }
 }
 
 // Initialize application
 function initApp() {
 // Your application code here
 console.log('Application initialized');
 }
 
 // Start when DOM is ready
 domReady(initApp);
})();

2. Multiple Initialization Scenarios

Sometimes you need to handle different scenarios based on when your code runs:

javascript
// Check if DOM is already ready
if (document.readyState === 'complete' || document.readyState === 'interactive') {
 // DOM is ready, run immediately
 initApp();
} else {
 // Wait for DOM to be ready
 document.addEventListener('DOMContentLoaded', initApp);
}
 
function initApp() {
 console.log('Initializing app');
 // Your initialization code
}

3. Dynamic Script Loading with DOM Ready

When dynamically loading scripts, ensure they’re loaded only after the DOM is ready:

javascript
function loadScript(url, callback) {
 const script = document.createElement('script');
 script.src = url;
 script.onload = callback;
 document.head.appendChild(script);
}
 
// Use DOM ready to load dependencies
document.addEventListener('DOMContentLoaded', function() {
 loadScript('https://cdn.example.com/library.js', function() {
 console.log('Library loaded, now initializing');
 initLibrary();
 });
});

4. Error Handling with DOM Ready

Always include error handling in your DOM ready implementation:

javascript
function safeDomReady(callback) {
 try {
 if (document.readyState === 'complete' || document.readyState === 'interactive') {
 setTimeout(callback, 1);
 } else if (document.addEventListener) {
 document.addEventListener('DOMContentLoaded', callback);
 } else {
 document.attachEvent('onreadystatechange', function() {
 if (document.readyState === 'complete') {
 callback();
 }
 });
 }
 } catch (error) {
 console.error('Error in DOM ready handler:', error);
 // Fallback in case of error
 window.addEventListener('load', callback);
 }
}
 
// Usage
safeDomReady(initApp);

5. Performance Optimization

For better performance, use passive event listeners where appropriate:

javascript
document.addEventListener('DOMContentLoaded', function() {
 // Your code here
}, { passive: true }); // Use passive for scroll/touch events if applicable

6. Combining with Modern JavaScript Features

You can use modern JavaScript features with DOM ready:

javascript
// Using arrow functions and template literals
document.addEventListener('DOMContentLoaded', () => {
 const elements = document.querySelectorAll('.my-class');
 
 elements.forEach(el => {
 el.textContent = `Element ${el.dataset.id} ready`;
 });
 
 // Using Promise-based approach
 Promise.resolve()
 .then(() => console.log('DOM ready and promises resolved'))
 .catch(error => console.error('Error:', error));
});

7. Framework-like Initialization Pattern

For larger applications, you might want a more structured approach:

javascript
const App = {
 init: function() {
 this.bindEvents();
 this.initializeComponents();
 this.setupAjax();
 console.log('Application initialized');
 },
 
 bindEvents: function() {
 // Event bindings
 document.addEventListener('click', this.handleDocumentClick.bind(this));
 },
 
 initializeComponents: function() {
 // Component initialization
 const accordions = document.querySelectorAll('.accordion');
 accordions.forEach(acc => new Accordion(acc));
 },
 // Other methods...
};
 
// Initialize when DOM is ready
document.addEventListener('DOMContentLoaded', () => App.init());

These best practices ensure that your code is robust, maintainable, and performs well across different browsers and devices.


Sources

  1. Tutorial Republic jQuery Document Ready Equivalent - Explanation of DOMContentLoaded event and vanilla JavaScript alternatives: https://www.tutorialrepublic.com/faq/jquery-document-ready-equivalent-in-javascript.php
  2. EnableGeek Tutorial on Document Ready - Comprehensive guide with browser compatibility table and multiple implementation methods: https://www.enablegeek.com/tutorial/document-ready-without-jquery/
  3. Beeker.io DOMContentLoaded Guide - Focus on modern browser solutions with IE9+ implementation details: https://beeker.io/jquery-document-ready-equivalent-vanilla-javascript
  4. Dev.to Replacing jQuery with Vanilla JS - Practical examples and comprehensive jQuery-to-vanilla JavaScript mapping: https://dev.to/rfornal/-replacing-jquery-with-vanilla-javascript-1k2g
  5. Dirask DOM Ready Equivalent - Basic implementation pattern and vanilla JavaScript examples: https://dirask.com/posts/JavaScript-document-ready-equivalent-without-jQuery-BDdAXp

Conclusion

The DOMContentLoaded event is the most direct and recommended vanilla JavaScript equivalent to jQuery’s $(document).ready() function. By using document.addEventListener("DOMContentLoaded", function() { /* code */ }), you can execute code after the DOM is fully loaded without the need for jQuery. This approach provides excellent performance, as it doesn’t wait for external resources to load before executing your JavaScript.

For browser compatibility, especially with older Internet Explorer versions, you may need to implement a polyfill that checks for document.readyState or uses the attachEvent method. Alternatively, you can place your script tags at the bottom of the HTML body, which ensures the DOM parsed before your script runs.

Understanding these different approaches to DOM ready detection is essential for modern web development. Whether you’re transitioning from jQuery or starting fresh with vanilla JavaScript, knowing how to properly time your DOM manipulations will help you create more reliable and performant web applications. The DOMContentLoaded event should be your go-to solution for most use cases, with other methods like window.onload or script placement serving as alternatives for specific requirements.

Authors
Verified by moderation
Vanilla JavaScript DOMContentLoaded: Document Ready Equivalent