DOMContentLoaded
is an event that is fired when the initial HTML document has been completely loaded and parsed, without waiting for stylesheets, images, and subframes to finish loading.
This means that at the time DOMContentLoaded
fires, the DOM tree is fully constructed, but external resources like images and stylesheets might still be loading allowing developers to execute JavaScript code as soon as the DOM is ready for manipulation, without waiting for all external resources to load.
Let's dive into an example:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="./style.css" />
<script src="./index.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
<div class="hello">Hello</div>
<button id="alert">Click</button>
<img id="img" src="https://en.js.cx/clipart/train.gif?speed=1&cache=0">
</body>
</html>
index.js
let getAlert = document.getElementById('alert')
getAlert.addEventListener('click',()=> {
alert("Button Clicked");
})
document.addEventListener('DOMContentLoaded', ()=>{
console.log("DOMContentLoaded fired!")
})
In this case the button will not work properly since we have our script at the head and the script is executing, the DOM has not fully loaded. Of course there are workarounds like putting the script at the end just before the body tag ends. But what if you want the script in the head and still you want to execute some commands which work on the DOM elements. Then use DOMContentLoaded
event as below:
document.addEventListener('DOMContentLoaded', ()=>{
console.log("DOMContentLoaded fired!")
let getAlert = document.getElementById('alert')
getAlert.addEventListener('click',()=> {
alert("Button Clicked");
})
})
Important Points:
The
DOMContentLoaded
event fires when the HTML document has been completely parsed, and all deferred scripts (<script defer src="…">
and<script type="mod
ule">
) have downloaded and executed. (Source: MDN)DOMContentLoaded
does not wait for stylesheets to load, however deferred scripts do wait for stylesheets, and theDOMContentLoaded
event is queued after deferred scripts. (Source: MDN)Scripts with
async
attribute does not block theDOMContentLoaded
event.Scripts that are generated dynamically with
document.createElement('script')
and then added to the webpage also don’t block this event.