⚡ JavaScript Topic Library

JavaScript Events — Clicks, Keys, Forms & Delegation

Events are how pages come alive — every click, keypress and form submit fires one. Master the listener pattern plus delegation and you can wire up any interface.

⚡ Quick Answer

Attach with el.addEventListener("click", handler). The handler receives an event object: e.target is what was clicked, e.preventDefault() stops default behavior (like form submission reloading the page).

§The listener pattern

listener.js
const btn = document.querySelector("#save");

btn.addEventListener("click", () => {
  console.log("saved!");
});

function onHover() { this.classList.add("hot"); }
btn.addEventListener("mouseenter", onHover);
btn.removeEventListener("mouseenter", onHover); // same reference!

§The event object

event_obj.js
document.addEventListener("click", (e) => {
  console.log(e.target);        // the exact element clicked
  console.log(e.clientX, e.clientY);   // mouse position
});

document.addEventListener("keydown", (e) => {
  if (e.key === "Escape") closeModal();
  if (e.ctrlKey && e.key === "s") {
    e.preventDefault();          // stop browser save dialog
    saveDraft();
  }
});

§Forms & preventDefault

forms.js
const form = document.querySelector("#signup");

form.addEventListener("submit", (e) => {
  e.preventDefault();            // stop the page reload!
  const data = new FormData(form);
  console.log(data.get("email"));
});

const input = document.querySelector("#name");
input.addEventListener("input", (e) => {
  preview.textContent = e.target.value;   // live as they type
});

§Event delegation — one listener, many targets

Instead of a listener per item (which breaks for items added later), listen on the parent and check what was clicked. Essential for dynamic lists.

delegation.js
const list = document.querySelector("#todos");

list.addEventListener("click", (e) => {
  const del = e.target.closest(".delete-btn");
  if (del) del.closest("li").remove();     // works for items
});                                         // added ANY time

// closest() climbs up from the click target to find a match

§Common Mistakes to Avoid

🚨 Watch out for these
  • Calling the handler while attachingaddEventListener("click", handle()) runs it now — pass handle without parentheses
  • Forgetting preventDefault on submit — the page reloads and your JS state vanishes — e.preventDefault() first
  • One listener per list item — breaks for dynamically added items and wastes memory — delegate from the parent

§Frequently Asked Questions

What is e.target vs e.currentTarget?

e.target is the innermost element actually clicked; e.currentTarget is the element the listener is attached to. In delegation you filter e.target.

What does preventDefault actually do?

It cancels the browser's built-in reaction — form submission reload, link navigation, checkbox toggle — leaving your JS in control.

What is event bubbling?

Events travel up from the clicked element through its ancestors — that's why a parent can catch children's clicks, which is what makes delegation possible.

How do I run code when the page is ready?

Put your script at the end of body, or use the defer attribute, or listen for DOMContentLoaded.

🎓 Want to master JavaScript properly?This reference covers one topic — the full free course takes you from zero to real projects, with quizzes and a certificate.
Start the Free JavaScript Course →

§Related JavaScript Topics

← DOM ManipulationAsync & Promises →