Skip to main content
โšก Calmops

Event Handling: addEventListener and Event Objects

Event Handling: addEventListener and Event Objects

Events are actions or occurrences that happen in the browser. Event handling allows you to respond to user interactions.

What are Events?

Events are triggered by user actions or browser actions:

// Click event
button.addEventListener("click", () => {
    console.log("Button clicked!");
});

// Keyboard event
document.addEventListener("keydown", (event) => {
    console.log(`Key pressed: ${event.key}`);
});

// Form event
form.addEventListener("submit", (event) => {
    event.preventDefault();
    console.log("Form submitted");
});

addEventListener()

The modern way to attach event listeners:

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

button.addEventListener("click", (event) => {
    console.log("Clicked!");
});

Event Types

// Mouse events
element.addEventListener("click", handler);
element.addEventListener("dblclick", handler);
element.addEventListener("mousedown", handler);
element.addEventListener("mouseup", handler);
element.addEventListener("mouseover", handler);
element.addEventListener("mouseout", handler);
element.addEventListener("mousemove", handler);

// Keyboard events
document.addEventListener("keydown", handler);
document.addEventListener("keyup", handler);
document.addEventListener("keypress", handler);

// Form events
form.addEventListener("submit", handler);
input.addEventListener("change", handler);
input.addEventListener("input", handler);
input.addEventListener("focus", handler);
input.addEventListener("blur", handler);

// Window events
window.addEventListener("load", handler);
window.addEventListener("resize", handler);
window.addEventListener("scroll", handler);

Event Object

The event object contains information about the event:

button.addEventListener("click", (event) => {
    console.log(event.type); // "click"
    console.log(event.target); // The element clicked
    console.log(event.currentTarget); // The element with listener
    console.log(event.timeStamp); // When event occurred
});

Common Event Properties

button.addEventListener("click", (event) => {
    // Type of event
    console.log(event.type); // "click"
    
    // Element that triggered event
    console.log(event.target);
    
    // Element with listener
    console.log(event.currentTarget);
    
    // Prevent default behavior
    event.preventDefault();
    
    // Stop propagation
    event.stopPropagation();
    
    // Check if default prevented
    console.log(event.defaultPrevented);
});

Mouse Events

Click Events

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

button.addEventListener("click", (event) => {
    console.log("Single click");
});

button.addEventListener("dblclick", (event) => {
    console.log("Double click");
});

Mouse Position

document.addEventListener("mousemove", (event) => {
    console.log(`X: ${event.clientX}, Y: ${event.clientY}`);
    console.log(`Page X: ${event.pageX}, Page Y: ${event.pageY}`);
});

Mouse Buttons

document.addEventListener("mousedown", (event) => {
    if (event.button === 0) console.log("Left click");
    if (event.button === 1) console.log("Middle click");
    if (event.button === 2) console.log("Right click");
});

Keyboard Events

Key Detection

document.addEventListener("keydown", (event) => {
    console.log(event.key); // "a", "Enter", "ArrowUp", etc.
    console.log(event.code); // "KeyA", "Enter", "ArrowUp", etc.
    console.log(event.keyCode); // Deprecated but still used
});

Modifier Keys

document.addEventListener("keydown", (event) => {
    if (event.ctrlKey) console.log("Ctrl pressed");
    if (event.shiftKey) console.log("Shift pressed");
    if (event.altKey) console.log("Alt pressed");
    if (event.metaKey) console.log("Meta pressed");
});

Keyboard Shortcuts

document.addEventListener("keydown", (event) => {
    // Ctrl+S
    if (event.ctrlKey && event.key === "s") {
        event.preventDefault();
        console.log("Save");
    }
    
    // Escape
    if (event.key === "Escape") {
        console.log("Close");
    }
});

Form Events

Input Events

const input = document.getElementById("myInput");

// Fires on every keystroke
input.addEventListener("input", (event) => {
    console.log(event.target.value);
});

// Fires when input loses focus
input.addEventListener("change", (event) => {
    console.log("Final value:", event.target.value);
});

Form Submission

const form = document.getElementById("myForm");

form.addEventListener("submit", (event) => {
    event.preventDefault(); // Prevent page reload
    
    const formData = new FormData(form);
    const data = Object.fromEntries(formData);
    
    console.log(data);
    // Send to server
});

Focus Events

const input = document.getElementById("myInput");

input.addEventListener("focus", (event) => {
    console.log("Input focused");
    event.target.style.borderColor = "blue";
});

input.addEventListener("blur", (event) => {
    console.log("Input blurred");
    event.target.style.borderColor = "gray";
});

Removing Event Listeners

function handleClick() {
    console.log("Clicked");
}

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

// Add listener
button.addEventListener("click", handleClick);

// Remove listener
button.removeEventListener("click", handleClick);

One-Time Listeners

button.addEventListener("click", () => {
    console.log("Clicked once");
}, { once: true });

Event Delegation

Handle events on parent instead of individual children:

// Without delegation - attach to each item
const items = document.querySelectorAll(".item");
items.forEach(item => {
    item.addEventListener("click", () => {
        console.log("Item clicked");
    });
});

// With delegation - attach to parent
const list = document.getElementById("list");
list.addEventListener("click", (event) => {
    if (event.target.classList.contains("item")) {
        console.log("Item clicked");
    }
});

Dynamic Elements

const list = document.getElementById("list");

// Event delegation handles dynamically added items
list.addEventListener("click", (event) => {
    if (event.target.tagName === "LI") {
        console.log("List item clicked:", event.target.textContent);
    }
});

// Add new item
const newItem = document.createElement("li");
newItem.textContent = "New item";
list.appendChild(newItem); // Event listener works!

Practical Examples

Button Click Counter

let count = 0;
const button = document.getElementById("myButton");
const counter = document.getElementById("counter");

button.addEventListener("click", () => {
    count++;
    counter.textContent = count;
});

Form Validation

const form = document.getElementById("myForm");
const emailInput = document.getElementById("email");

emailInput.addEventListener("blur", (event) => {
    const email = event.target.value;
    const isValid = email.includes("@");
    
    if (!isValid) {
        event.target.classList.add("error");
    } else {
        event.target.classList.remove("error");
    }
});

form.addEventListener("submit", (event) => {
    event.preventDefault();
    console.log("Form submitted");
});

Search Filter

const searchInput = document.getElementById("search");
const items = document.querySelectorAll(".item");

searchInput.addEventListener("input", (event) => {
    const query = event.target.value.toLowerCase();
    
    items.forEach(item => {
        const text = item.textContent.toLowerCase();
        item.style.display = text.includes(query) ? "block" : "none";
    });
});

Keyboard Navigation

const items = document.querySelectorAll(".item");
let currentIndex = 0;

document.addEventListener("keydown", (event) => {
    if (event.key === "ArrowDown") {
        currentIndex = (currentIndex + 1) % items.length;
        items[currentIndex].focus();
    } else if (event.key === "ArrowUp") {
        currentIndex = (currentIndex - 1 + items.length) % items.length;
        items[currentIndex].focus();
    }
});

Drag and Drop

let draggedElement = null;

document.addEventListener("dragstart", (event) => {
    draggedElement = event.target;
    event.target.style.opacity = "0.5";
});

document.addEventListener("dragend", (event) => {
    event.target.style.opacity = "1";
});

const dropZone = document.getElementById("dropZone");

dropZone.addEventListener("dragover", (event) => {
    event.preventDefault();
    dropZone.style.backgroundColor = "lightblue";
});

dropZone.addEventListener("drop", (event) => {
    event.preventDefault();
    dropZone.appendChild(draggedElement);
    dropZone.style.backgroundColor = "white";
});

Event Options

// Capture phase
element.addEventListener("click", handler, true);

// Options object
element.addEventListener("click", handler, {
    capture: false,
    once: false,
    passive: false
});

// Passive listener (can't call preventDefault)
element.addEventListener("scroll", handler, { passive: true });

Summary

  • addEventListener(): attach event listeners
  • Event object: contains event information
  • Event types: click, keydown, submit, etc.
  • preventDefault(): stop default behavior
  • stopPropagation(): stop event bubbling
  • Event delegation: handle events on parent
  • removeEventListener(): detach listeners
  • Best practice: use event delegation for dynamic content

Official Documentation

Next Steps

  1. Event Delegation and Event Propagation
  2. Event Bubbling and Capturing
  3. Form Handling and Validation

Comments