AiTechWorlds
AiTechWorlds
University learning companion
Web Development Bootcamp 2026 · Event Handling & Delegation
A feature looks correct on a developer’s large monitor but fails on a slow connection and a small screen. Use this topic to inspect structure, state, loading/error behaviour, accessibility and the user journey—not just the happy path.
Use this course-level map to place “Event Handling & Delegation” in the larger system. It complements—not replaces—a topic-specific worked diagram.
Events connect user actions to your JavaScript code. Understanding event delegation attaching one listener to a parent instead of many listeners to children is what makes dynamic UIs performant.
const btn = document.querySelector("#submit");
btn.addEventListener("click", (event) => {
event.preventDefault();
console.log("Clicked!");
});
// Named function (can be removed later)
function handleClick(e) {
console.log(e.target);
}
btn.addEventListener("click", handleClick);
btn.removeEventListener("click", handleClick);
// Options: once, passive, capture
btn.addEventListener("click", handleClick, { once: true });
window.addEventListener("scroll", onScroll, { passive: true });Instead of adding listeners to every child element, add ONE to a parent. This works for dynamically added elements too:
// ❌ Adding to every item — breaks when items are added dynamically
document.querySelectorAll(".todo-item").forEach(item => {
item.addEventListener("click", handleItemClick);
});
// ✅ One listener on the parent
const list = document.querySelector(".todo-list");
list.addEventListener("click", (event) => {
// Find the closest ancestor matching the selector
const item = event.target.closest(".todo-item");
if (!item) return; // clicked on list but not an item
const id = item.dataset.id;
if (event.target.matches(".delete-btn")) deleteItem(id);
if (event.target.matches(".complete-btn")) toggleItem(id);
if (event.target.matches(".edit-btn")) editItem(id);
});// Mouse
element.addEventListener("click", handler);
element.addEventListener("dblclick", handler);
element.addEventListener("mouseenter", handler); // fires only on element
element.addEventListener("mouseleave", handler);
element.addEventListener("mouseover", handler); // fires on children too
element.addEventListener("contextmenu", (e) => {
e.preventDefault(); // custom right-click menu
});
// Keyboard
document.addEventListener("keydown", (e) => {
if (e.key === "Enter") submit();
if (e.key === "Escape") closeModal();
if (e.ctrlKey && e.key === "s") save();
if (e.key === "ArrowUp") navigateUp();
});
// Form
form.addEventListener("submit", (e) => {
e.preventDefault();
processForm(new FormData(form));
});
input.addEventListener("input", (e) => { // every keystroke
updatePreview(e.target.value);
});
input.addEventListener("change", handler); // after blur
input.addEventListener("focus", handler);
input.addEventListener("blur", handler);
// Window
window.addEventListener("resize", debounce(handleResize, 100));
window.addEventListener("scroll", throttle(handleScroll, 16), { passive: true });
document.addEventListener("DOMContentLoaded", init);
window.addEventListener("load", onFullyLoaded);
window.addEventListener("beforeunload", saveState);element.addEventListener("click", (event) => {
event.target; // element that triggered the event
event.currentTarget; // element the listener is on
event.type; // "click"
event.timeStamp; // when it happened
// Mouse
event.clientX; // viewport coordinates
event.pageX; // page coordinates (includes scroll)
event.button; // 0=left, 1=middle, 2=right
// Keyboard
event.key; // "Enter", "a", "ArrowUp"
event.code; // "KeyA" (physical key)
event.shiftKey;
event.ctrlKey;
event.altKey;
event.metaKey; // Cmd / Windows key
// Control
event.preventDefault(); // stop default behavior
event.stopPropagation(); // stop bubbling
});// Debounce — wait until user stops
function debounce(fn, delay) {
let timer;
return (...args) => {
clearTimeout(timer);
timer = setTimeout(() => fn(...args), delay);
};
}
const searchInput = document.querySelector("#search");
searchInput.addEventListener("input", debounce((e) => {
fetch(`/api/search?q=${e.target.value}`).then(r => r.json()).then(renderResults);
}, 300));
// Throttle — fire at most once per interval
function throttle(fn, limit) {
let inThrottle;
return (...args) => {
if (!inThrottle) {
fn(...args);
inThrottle = true;
setTimeout(() => inThrottle = false, limit);
}
};
}
window.addEventListener("scroll", throttle(updateScrollProgress, 16), { passive: true });function trapFocus(modal) {
const focusable = modal.querySelectorAll(
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
);
const first = focusable[0];
const last = focusable[focusable.length - 1];
modal.addEventListener("keydown", (e) => {
if (e.key !== "Tab") return;
if (e.shiftKey) {
if (document.activeElement === first) {
last.focus();
e.preventDefault();
}
} else {
if (document.activeElement === last) {
first.focus();
e.preventDefault();
}
}
});
first.focus();
}Next lesson: Fetch API & Async JavaScript loading data from servers without page reloads.
University learning companion
Web Development Bootcamp 2026 · Event Handling & Delegation
Complete the steps without looking at the answer first; record evidence rather than only a final result.
These are primary or established learning references for this subject. Check the relevant chapter or specification for the exact topic and version.
Get this course's notes on Telegram!
Free cheat sheets, summaries & practice exercises