
Quick answer: A JavaScript event is something that happens — a click, a key press, a form submit. You listen with addEventListener, read details from the event object, and handle bubbling with stopPropagation or delegation. Every listener you add should have a matching way to be removed, and forms need preventDefault to stop the page reloading.The sections below cover JavaScript events from the listener up: common event types, the event object, bubbling and delegation, and the controls you should not hand-roll because JavaScript events already handle them.
Table of Contents
Adding a listener
const button = document.querySelector("button");
function onClick(event) {
console.log("clicked", event.target);
}
button.addEventListener("click", onClick);
button.removeEventListener("click", onClick); // clean up when doneAlways pass a named or arrow function rather than an inline string, and keep a reference if you will need to remove it later. In a single-page app, a listener left on a removed element is a memory leak.
Common JavaScript events and their uses
| Event | Fires when |
|---|---|
click | The element is activated |
input | A field’s value changes as the user types |
change | A field loses focus after changing |
submit | A form is submitted |
keydown / keyup | A key is pressed or released |
DOMContentLoaded | The HTML is parsed and ready |
Use input for live search and character counts, because it fires on every keystroke. Use change when you only care about the final value.
The event object
document.querySelector("form").addEventListener("submit", (e) => {
e.preventDefault(); // stop the full-page reload
const data = new FormData(e.target);
console.log(Object.fromEntries(data));
});
document.addEventListener("keydown", (e) => {
if (e.key === "Escape") closeModal();
});event.target— the element the event originated on.event.currentTarget— the element whose listener is running.event.key— the key name, such as"Enter"or"Escape".event.preventDefault()— cancel the default browser action.
Bubbling and delegation in JavaScript events
Events bubble: a click on a nested element travels up through its ancestors. That makes delegation possible — one listener on a container can handle clicks on any child, including children added later.
document.querySelector("#list").addEventListener("click", (e) => {
const row = e.target.closest("[data-id]");
if (!row) return;
select(row.dataset.id);
});Delegation is the answer to the classic bug where listeners on individual rows stop working after you re-render the list. One listener on the parent survives every re-render.
Controls you should not hand-roll
Modern HTML gives you behaviour that used to require JavaScript. Reach for these before writing listeners:
<dialog id="modal">
<p>Native modal with focus trapping.</p>
<form method="dialog"><button>Close</button></form>
</dialog>
<button popovertarget="menu">Open menu</button>
<div id="menu" popover>Popover content</div>
<details>
<summary>Accordion header</summary>
<p>No JavaScript needed.</p>
</details>The <dialog> element handles focus management and the backdrop for you, and the popover attribute toggles a lightweight overlay with no script. When you do need script, dialog.showModal() opens the modal with the correct accessibility behaviour.
Next: modern JavaScript syntax. To learn events and the DOM with a mentor, Ampersand Academy teaches web development one-to-one.
Frequently asked questions
What is event bubbling in JavaScript?
An event starts on the target element and travels up through its ancestors. Each ancestor’s listener can handle it, which enables delegation with a single listener on a parent.
How do I stop a form from reloading the page?
Call event.preventDefault() inside the submit handler. That cancels the browser’s default navigation so you can handle the data with JavaScript or fetch.
What is event delegation?
Attaching one listener to a parent and using event.target to find which child was clicked. It keeps working for elements added after the listener was set up.
Why do my event listeners stop working after re-rendering?
The old elements were removed along with their listeners. Use event delegation on a container that stays in the DOM, or re-attach listeners after rendering.
Do I need JavaScript for a modal dialog?
Often less than you think. The dialog element and the popover attribute provide accessible modals and overlays, and details gives you an accordion with no script.
Last updated on · Written by Dinesh Kumar R

