← JS Mastery | Module 5: DOM Manipulation Events & Event Listeners
Module 5

Events & Event Listeners

⏱ 22 min read ● Intermediate 🆓 Free

Event Listeners

Events are things that happen in the browser — clicks, key presses, form submissions, page loads. JavaScript lets you "listen" for these events and run code when they occur.

// Adding event listeners:
const button = document.querySelector("#myButton");

button.addEventListener("click", function(event) {
  console.log("Button clicked!", event);
});

// Arrow function (no 'this' binding):
button.addEventListener("click", (e) => {
  console.log("Clicked at:", e.clientX, e.clientY);
});

// Named function (easier to remove later):
function handleClick(e) {
  console.log("Handled!");
}
button.addEventListener("click", handleClick);
button.removeEventListener("click", handleClick);  // remove it

// Options object:
button.addEventListener("click", handler, {
  once: true,      // fire only once, then auto-remove
  passive: true,   // won't call preventDefault (performance)
  capture: true    // fire in capture phase (rare)
});

The Event Object

document.addEventListener("click", (event) => {
  // Common event properties:
  event.type;           // "click"
  event.target;         // element that was clicked
  event.currentTarget;  // element the listener is attached to
  event.clientX;        // click X position in viewport
  event.clientY;        // click Y position in viewport
  event.pageX;          // click X relative to document
  event.timeStamp;      // when the event fired (ms)

  // Prevent default behavior:
  event.preventDefault();  // e.g., prevent link navigation
  
  // Stop propagation:
  event.stopPropagation(); // don't bubble to parent elements
});

// Keyboard events:
document.addEventListener("keydown", (e) => {
  e.key;        // "Enter", "Escape", "a", "ArrowLeft"
  e.code;       // "Enter", "Escape", "KeyA", "ArrowLeft"
  e.ctrlKey;    // true if Ctrl held
  e.shiftKey;   // true if Shift held
  e.altKey;     // true if Alt held
  e.metaKey;    // true if Cmd/Win key held
  
  if (e.key === "Escape") closeModal();
  if (e.ctrlKey && e.key === "s") saveDocument(e);
});

// Form events:
form.addEventListener("submit", (e) => {
  e.preventDefault();  // ALWAYS prevent default on forms you handle!
  const data = new FormData(e.target);
  const name = data.get("name");
});

Event Bubbling & Delegation

// Event bubbling: events fire on target, then bubble up to parents
// Click on  inside 
inside : // 1. span handler fires // 2. div handler fires // 3. body handler fires // 4. document handler fires // Event delegation — attach ONE listener to parent, handle multiple children: const list = document.querySelector("ul"); list.addEventListener("click", (e) => { // e.target is the actual clicked element if (e.target.tagName === "LI") { e.target.classList.toggle("completed"); } }); // Why delegation is better than adding listener to each item: // - Works for dynamically added elements! // - Better performance (one listener vs many) // - Less memory usage // Practical delegation with closest(): document.querySelector(".product-list").addEventListener("click", (e) => { const btn = e.target.closest("[data-action]"); if (!btn) return; const action = btn.dataset.action; const productId = btn.closest(".product-card").dataset.id; if (action === "add-to-cart") addToCart(productId); if (action === "wishlist") addToWishlist(productId); });

Common Events Reference

EventWhen It FiresCommon Use
clickMouse clickButtons, links
dblclickDouble clickEdit mode
mouseover/outHover enter/leaveTooltips
keydown/upKey pressed/releasedShortcuts, input
inputValue changesReal-time validation
changeInput loses focusSelect, checkbox
submitForm submittedForm handling
focus/blurElement gets/loses focusInput validation
scrollPage scrollsSticky nav, lazy load
resizeWindow resizedResponsive JS
DOMContentLoadedDOM readyInit code
loadPage fully loadedImages loaded

⚡ Key Takeaways

🎯 Practice Exercises

EXERCISE 1

Build a keyboard shortcut handler: Ctrl+S calls save(), Ctrl+Z calls undo(), Escape closes the current modal. Use one keydown listener on document.

EXERCISE 2 — CHALLENGE

Build a dynamic todo list using event delegation: one click listener on the list handles adding, completing, and deleting items (via data-action attributes).

← Selectors