HTML DOM Events

Handling user interactions and browser events with JavaScript

⚡ What are DOM Events?

DOM events are actions that happen in the browser - like clicks, key presses, or page loads. JavaScript can "listen" for these events and respond to them.


// Simple event handling
let button = document.getElementById("myButton");
button.addEventListener("click", function() {
    alert("Button was clicked!");
});
                                    

Try it:

Common Event Types

🖱️

Mouse Events

Click, hover, drag interactions

click, dblclick, mousedown
mouseup, mouseover, mouseout
⌨️

Keyboard Events

Key press and release events

keydown, keyup, keypress
📝

Form Events

Form submission and input changes

submit, change, input
focus, blur
🪟

Window Events

Page load and resize events

load, resize, scroll
beforeunload

🔹 Adding Event Listeners

Different ways to handle events in JavaScript:

let button = document.getElementById("myButton");

// Method 1: HTML attribute (not recommended)
// <button onclick="alert('Clicked!')">Click me</button>

// Method 2: Element property
button.onclick = function() {
    console.log("Button clicked!");
};

// Method 3: addEventListener (recommended)
button.addEventListener("click", function() {
    console.log("Button clicked with addEventListener!");
});

// Method 3 with named function
function handleClick() {
    console.log("Named function called!");
}
button.addEventListener("click", handleClick);

// Multiple event listeners
button.addEventListener("click", function() {
    console.log("First listener");
});
button.addEventListener("click", function() {
    console.log("Second listener");
});

// Event listener with options
button.addEventListener("click", handleClick, {
    once: true,        // Run only once
    passive: true,     // Never calls preventDefault
    capture: false     // Don't capture during capture phase
});

Output (when button is clicked):

Button clicked!
Button clicked with addEventListener!
Named function called!
First listener
Second listener

🔹 Mouse Events

Handle different mouse interactions:

let box = document.getElementById("interactiveBox");

// Click events
box.addEventListener("click", function(event) {
    console.log("Single click at:", event.clientX, event.clientY);
});

box.addEventListener("dblclick", function() {
    console.log("Double click!");
});

// Mouse button events
box.addEventListener("mousedown", function(event) {
    console.log("Mouse button pressed:", event.button);
    // 0 = left, 1 = middle, 2 = right
});

box.addEventListener("mouseup", function() {
    console.log("Mouse button released");
});

// Mouse movement events
box.addEventListener("mouseover", function() {
    box.style.backgroundColor = "lightblue";
    console.log("Mouse entered");
});

box.addEventListener("mouseout", function() {
    box.style.backgroundColor = "lightgray";
    console.log("Mouse left");
});

box.addEventListener("mousemove", function(event) {
    // Get mouse position relative to element
    let rect = box.getBoundingClientRect();
    let x = event.clientX - rect.left;
    let y = event.clientY - rect.top;
    console.log("Mouse position in box:", x, y);
});

// Context menu (right-click)
box.addEventListener("contextmenu", function(event) {
    event.preventDefault(); // Prevent default context menu
    console.log("Right-clicked!");
});

Interactive Demo:

Hover and Click Me!

🔹 Keyboard Events

Capture and respond to keyboard input:

let input = document.getElementById("textInput");

// Key press events
input.addEventListener("keydown", function(event) {
    console.log("Key pressed:", event.key);
    console.log("Key code:", event.keyCode);
    console.log("Ctrl pressed:", event.ctrlKey);
    console.log("Shift pressed:", event.shiftKey);
    console.log("Alt pressed:", event.altKey);
});

input.addEventListener("keyup", function(event) {
    console.log("Key released:", event.key);
});

// Specific key detection
input.addEventListener("keydown", function(event) {
    if (event.key === "Enter") {
        console.log("Enter key pressed!");
        event.preventDefault(); // Prevent default action
    }
    
    if (event.key === "Escape") {
        input.blur(); // Remove focus
    }
    
    if (event.ctrlKey && event.key === "s") {
        event.preventDefault(); // Prevent browser save
        console.log("Ctrl+S pressed - custom save action");
    }
});

// Input event (fires on every change)
input.addEventListener("input", function(event) {
    console.log("Input value:", event.target.value);
    console.log("Input length:", event.target.value.length);
});

// Global keyboard events (on document)
document.addEventListener("keydown", function(event) {
    if (event.key === "F1") {
        event.preventDefault();
        console.log("F1 pressed - show help");
    }
});

Try typing:

🔹 Form Events

Handle form interactions and validation:

let form = document.getElementById("myForm");
let nameInput = document.getElementById("nameInput");
let emailInput = document.getElementById("emailInput");

// Form submission
form.addEventListener("submit", function(event) {
    event.preventDefault(); // Prevent default form submission
    
    let name = nameInput.value;
    let email = emailInput.value;
    
    if (name === "" || email === "") {
        alert("Please fill in all fields");
        return;
    }
    
    console.log("Form submitted:", {name, email});
});

// Input focus events
nameInput.addEventListener("focus", function() {
    this.style.backgroundColor = "lightyellow";
    console.log("Name input focused");
});

nameInput.addEventListener("blur", function() {
    this.style.backgroundColor = "white";
    console.log("Name input lost focus");
    
    // Validation on blur
    if (this.value.length < 2) {
        this.style.borderColor = "red";
    } else {
        this.style.borderColor = "#ccc";
    }
});

// Input change events
emailInput.addEventListener("change", function() {
    console.log("Email changed to:", this.value);
    
    // Simple email validation
    let emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    if (!emailPattern.test(this.value)) {
        this.style.borderColor = "red";
        console.log("Invalid email format");
    } else {
        this.style.borderColor = "green";
        console.log("Valid email format");
    }
});

// Real-time input validation
nameInput.addEventListener("input", function() {
    let value = this.value;
    let feedback = document.getElementById("nameFeedback");
    
    if (value.length < 2) {
        feedback.textContent = "Name must be at least 2 characters";
        feedback.style.color = "red";
    } else {
        feedback.textContent = "Good!";
        feedback.style.color = "green";
    }
});

Interactive Form:

🔹 Event Object Properties

The event object contains useful information about the event:

button.addEventListener("click", function(event) {
    // Event type and target
    console.log("Event type:", event.type);           // "click"
    console.log("Target element:", event.target);     // Element that triggered event
    console.log("Current target:", event.currentTarget); // Element with event listener
    
    // Mouse position
    console.log("Client X:", event.clientX);          // X relative to viewport
    console.log("Client Y:", event.clientY);          // Y relative to viewport
    console.log("Page X:", event.pageX);              // X relative to document
    console.log("Page Y:", event.pageY);              // Y relative to document
    console.log("Screen X:", event.screenX);          // X relative to screen
    console.log("Screen Y:", event.screenY);          // Y relative to screen
    
    // Modifier keys
    console.log("Ctrl key:", event.ctrlKey);          // true/false
    console.log("Shift key:", event.shiftKey);        // true/false
    console.log("Alt key:", event.altKey);            // true/false
    console.log("Meta key:", event.metaKey);          // Cmd/Windows key
    
    // Event control
    event.preventDefault();    // Prevent default action
    event.stopPropagation();  // Stop event bubbling
    
    // Timing
    console.log("Timestamp:", event.timeStamp);       // When event occurred
});

// Keyboard event properties
input.addEventListener("keydown", function(event) {
    console.log("Key:", event.key);                   // "a", "Enter", "Shift"
    console.log("Code:", event.code);                 // "KeyA", "Enter", "ShiftLeft"
    console.log("Key Code:", event.keyCode);          // Numeric code (deprecated)
    console.log("Which:", event.which);               // Numeric code (deprecated)
    console.log("Repeat:", event.repeat);             // true if key is held down
});

Output (when events occur):

Event type: click
Target element: [object HTMLButtonElement]
Client X: 150
Client Y: 200
Ctrl key: false
Key: a
Code: KeyA
Repeat: false

🔹 Event Bubbling and Capturing

Understanding how events propagate through the DOM:

// HTML structure:
// <div id="outer">
//   <div id="middle">
//     <button id="inner">Click me</button>
//   </div>
// </div>

let outer = document.getElementById("outer");
let middle = document.getElementById("middle");
let inner = document.getElementById("inner");

// Event bubbling (default) - from target to root
outer.addEventListener("click", function() {
    console.log("Outer div clicked (bubbling)");
});

middle.addEventListener("click", function() {
    console.log("Middle div clicked (bubbling)");
});

inner.addEventListener("click", function(event) {
    console.log("Button clicked");
    // event.stopPropagation(); // Uncomment to stop bubbling
});

// Event capturing - from root to target
outer.addEventListener("click", function() {
    console.log("Outer div clicked (capturing)");
}, true); // true enables capturing

middle.addEventListener("click", function() {
    console.log("Middle div clicked (capturing)");
}, true);

// When button is clicked, order will be:
// 1. Outer div clicked (capturing)
// 2. Middle div clicked (capturing)
// 3. Button clicked
// 4. Middle div clicked (bubbling)
// 5. Outer div clicked (bubbling)

// Event delegation - handle events on parent
let list = document.getElementById("itemList");
list.addEventListener("click", function(event) {
    if (event.target.tagName === "LI") {
        console.log("List item clicked:", event.target.textContent);
    }
});

// This works even for dynamically added items
let newItem = document.createElement("li");
newItem.textContent = "New item";
list.appendChild(newItem); // Click events will still work

Output (when button is clicked):

Outer div clicked (capturing)
Middle div clicked (capturing)
Button clicked
Middle div clicked (bubbling)
Outer div clicked (bubbling)

🧠 Test Your Knowledge

Which method is recommended for adding event listeners?