JavaScript events are signals fired by the browser when users click buttons, type in inputs, submit forms, or resize the window. Listening for events lets your application react immediately without reloading the page.
When you click a nested <button> inside a <div>, the event travels down during capturing, hits the target button, and bubbles back up through parent elements.
flowchart TD
Win["window / document"] -- "1. Capture phase" --> Card["div.card"]
Card -- "1. Capture phase" --> Btn["button (2. Target phase)"]
Btn -- "3. Bubble phase" --> Card2["div.card"]
Card2 -- "3. Bubble phase" --> Win2["window / document"]
addEventListener()Always use addEventListener(eventName, handler) instead of HTML onclick attributes or element.onclick = fn. You can attach multiple listeners to one element and inspect the event object passed to your callback.
const form = document.querySelector("#signup-form");
const emailInput = document.querySelector("#email");
if (form && emailInput) {
emailInput.addEventListener("input", (event) => {
console.log("Current value:", event.target.value);
});
form.addEventListener("submit", (event) => {
event.preventDefault(); // Stop full page reload
console.log("Submitting:", emailInput.value.trim());
});
}
event.target: The exact inner element that triggered the event.event.currentTarget: The element to which the listener is attached.event.preventDefault(): Cancels default browser behavior such as form submission or link navigation.element.onclick: Setting btn.onclick = secondFn silently replaces any earlier btn.onclick handler. Use addEventListener instead.<ul> and inspect event.target.closest("li") (event delegation).event.preventDefault() on forms: Without it, submitting a form reloads the entire page and wipes your JavaScript state.input and change events?The input event fires on every keystroke or paste immediately. The change event fires on text inputs only after the field loses focus and its value changed.
event.stopPropagation() do?event.stopPropagation() stops the event from bubbling up to ancestor elements. Use it sparingly so global click-outside handlers do not break.
Pass the exact same named function reference to element.removeEventListener("click", handleSave), or pass { signal: controller.signal } using AbortController.
Sign in to track your learning journey, earn industry-recognized certificates, and join our elite developer community.
Quick Access With
Experiment with the code from this lesson in our interactive playground.