Warming up the neural circuits...
The (Document Object Model) is the browser's tree representation of your . can reach into this tree and change anything — text, attributes, styles, structure — in response to user actions.
HTML (text file) DOM (live tree in browser)
┌──────────────┐ ┌──────────────────────────┐
│ <h1>Hello</h1>│ ──→ │ document │
│ <p>World</p> │ │ ├── html │
└──────────────┘ │ │ ├── head │
│ │ └── body │
│ │ ├── h1 "Hello" │
│ │ └── p "World" │
└──────────────────────────┘
↑ JavaScript can modify this// By ID (fastest)
const header = document.getElementById("header");
// By CSS selector (most versatile)
const button = document.querySelector(".btn-primary");
const firstItem = document.querySelector("ul li:first-child");// By CSS selector (returns NodeList)
const buttons = document.querySelectorAll(".btn");
console.log(buttons.length); // Number of buttons
buttons.forEach(btn => console.log
const el = document.querySelector("h1");
el.textContent = "New Title"; // Changes text (safe, no HTML)
el.innerHTML = "<span>New Title</span>"; // Changes HTML (⚠️ XSS risk with user input)
elconst img = document.querySelector("img");
img.src = "new-image.jpg";
img.alt = "New description";
img.setAttribute("title", "Tooltip text
const el = document.querySelector(".card");
el.classList.add("active"); // Add class
el.classList.remove("hidden"); //
const el = document.querySelector(".box");
el.style.color = "red";
el.style.backgroundColor = "#f0f0f0"; // camelCase (not background-color)
el
// Create
const div = document.createElement("div");
div.textContent = "Hello World";
div.className = "card";
div.id = "
Events are how users interact with your page.
const button = document.querySelector("button");
// Add event listener
button.addEventListener("click", () => {
console.log("Button clicked!");
});
// Mouse events
element.addEventListener("click", fn); // Click
element.addEventListener("dblclick", fn); // Double click
element.addEventListener("mouseenter
Every event handler receives an event object with useful properties:
element.addEventListener("click", (event) => {
event.target; // The element that was clicked
event.currentTarget; // The element with the listener
event.type; // "click"
When you click a nested , the event travels through three phases:
Capturing phase (down)
┌─ document
│ ┌─ html
│ │ ┌─ body
│ │ │ ┌─ div.container
│ │ │ │ ┌─ button (target)
│ │ │ │ └─ click!
│ │ │ └─ bubbling up
│ │ └─ bubbling up
│ └─ bubbling up
└─ bubbling up (default)<div id="parent">
<button id="child">Click me</button>
</div>document.getElementById("parent").addEventListener("click", () => {
console.log("Parent clicked (bubbling)");
});
document.getElementById("child").addEventListener(
Event Delegation pattern: Listen on a parent to handle many children:
// Instead of adding a listener to each item...
document.querySelector("ul").addEventListener("click", (e) => {
if (e.target.tagName === "LI") {
console.
<div class="accordion">
<button class="accordion-btn">Section 1</button>
<div class="accordion-panel">Content 1</div>
<button class="accordion-btn">Section 2
const toggle = document.getElementById("theme-toggle");
toggle.addEventListener("click", () => {
document.body.classList.toggle("dark-mode");
});const input = document.querySelector("textarea");
const counter = document.querySelector(".char-count");
input.addEventListener("input", () => {
counter.textContent
Mistake 1: Using innerHTML with user (XSS risk)
// ❌ Dangerous! User can inject scripts
element.innerHTML = userInput;
// ✅ Safe
element.textContent = userInput;Mistake 2: Adding event listeners in a loop with var
// ❌ Wrong (all buttons log "Button 3")
for (var i = 0; i < buttons.length; i++) {
buttons[i].addEventListener("click", () => console.log(i
Mistake 3: Querying DOM before it exists
// ❌ Wrong (script in head — element doesn't exist yet)
const el = document.querySelector(".not-loaded-yet");
// ✅ Put scripts at end of body, or use DOMContentLoaded
document.addEventListener("DOMContentLoaded", () => {
const el = document.querySelector(