Episode 18 of 18
DOMContentLoaded Event
Ensure your JavaScript runs at the right time — use DOMContentLoaded to wait for the DOM to be ready before manipulating elements.
DOMContentLoaded Event
If your JavaScript runs before the HTML is fully parsed, it will not find any elements — querySelector returns null. The DOMContentLoaded event fires when the HTML has been completely parsed and the DOM tree is ready.
The Problem
<head>
<script>
// This runs BEFORE the body is parsed!
var title = document.querySelector('h1');
console.log(title); // null — the <h1> does not exist yet
</script>
</head>
<body>
<h1>Hello World</h1>
</body>
The Solution: DOMContentLoaded
<head>
<script>
document.addEventListener('DOMContentLoaded', function() {
// Runs AFTER the DOM is fully parsed
var title = document.querySelector('h1');
console.log(title.textContent); // "Hello World" ✓
});
</script>
</head>
<body>
<h1>Hello World</h1>
</body>
DOMContentLoaded vs load
| Event | Fires When | Use For |
|---|---|---|
DOMContentLoaded | HTML parsed, DOM ready (images may still load) | DOM manipulation, event binding |
load | Everything loaded (images, stylesheets, iframes) | Tasks needing fully loaded resources |
Alternatives
<!-- Option 1: DOMContentLoaded -->
<head>
<script>
document.addEventListener('DOMContentLoaded', function() {
// DOM ready
});
</script>
</head>
<!-- Option 2: Script at the bottom (most common) -->
<body>
<h1>Hello</h1>
<script src="app.js"></script> <!-- DOM is already parsed -->
</body>
<!-- Option 3: defer attribute -->
<head>
<script src="app.js" defer></script> <!-- Runs after DOM parsed -->
</head>
Which to Use?
| Approach | Pros | Cons |
|---|---|---|
DOMContentLoaded | Explicit, works anywhere | Slightly more code |
| Script at bottom | Simple, no wrapper needed | All HTML must be above the script |
defer attribute | Clean, modern | Only works with external scripts |
Series Wrap-up
Congratulations! You now have a solid understanding of the JavaScript DOM. You have learned to:
- Select elements with getElementById, querySelector, and getElementsByClassName
- Traverse the DOM tree — parents, children, and siblings
- Change content, styles, classes, and attributes
- Create and remove elements dynamically
- Listen for and handle events, including delegation and bubbling
- Build real UI patterns like search filters and tabbed content
Key Takeaways
DOMContentLoadedwaits for the DOM tree to be ready — not images or stylesheets- Place scripts at the bottom of the body or use
deferfor the simplest approach - The
loadevent waits for everything — use only when you need fully loaded resources - Understanding script timing prevents null reference errors