Skip to content
Happy Programming Guide
Start learning
JavaScript

JavaScript Events Explained

How to react to clicks, typing and form submissions. Event listeners, the event object, preventDefault, and delegation for elements that do not exist yet.

An event is something that happens on the page — a click, a key press, a form submission. JavaScript lets you run code when one occurs.

JavaScript
const button = document.querySelector("#save");

button.addEventListener("click", () => {
  console.log("Saved");
});

The pattern#

JavaScript
element.addEventListener("eventName", callbackFunction);

Three parts: what to watch, what to watch for, and what to do. The function runs later, whenever the event happens.

The events you will actually use#

Event Fires when
click Anything is clicked or tapped
input A field’s value changes, on every keystroke
change A field loses focus after changing, or a select changes
submit A form is submitted
keydown A key goes down
DOMContentLoaded The HTML has finished parsing

The event object#

Your callback receives an object describing what happened.

JavaScript
document.querySelector("#name").addEventListener("input", (event) => {
  console.log(event.target.value);   // what is currently typed
});

document.addEventListener("keydown", (event) => {
  if (event.key === "Escape") closeMenu();
});

event.target is the element the event actually happened on. It is the most useful property on the object by far.

Forms: stopping the page reload#

By default, submitting a form reloads the page. That is almost never what you want in a JavaScript app.

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

form.addEventListener("submit", (event) => {
  event.preventDefault();          // stop the reload

  const email = form.querySelector("#email").value.trim();
  if (!email.includes("@")) {
    console.log("Please enter a valid email address");
    return;
  }

  console.log("Submitting", email);
});

Listen for submit on the form, not click on the button. That way pressing Enter in a field works too, which matters for keyboard users.

Event delegation#

A listener attached to a button that does not exist yet will never fire. Instead, listen on a parent that does exist and work out what was clicked.

JavaScript
const list = document.querySelector("#todo-list");

list.addEventListener("click", (event) => {
  const deleteButton = event.target.closest(".delete");
  if (!deleteButton) return;                 // clicked something else

  deleteButton.closest("li").remove();
});

One listener handles every item, including ones you add later. This is the standard solution for dynamic lists.

Bubbling#

Events travel upward from the element to its ancestors. That is what makes delegation work. Occasionally you need to stop it:

JavaScript
innerButton.addEventListener("click", (event) => {
  event.stopPropagation();      // do not let the parent also react
});

Use this sparingly — it can make behaviour hard to trace later.

Removing a listener#

JavaScript
function onScroll() { console.log("scrolling"); }

window.addEventListener("scroll", onScroll);
window.removeEventListener("scroll", onScroll);    // needs the same reference

This only works with a named function. An inline arrow function cannot be removed, because you no longer have a reference to it.

Questions people ask#

What is the difference between input and change?

input fires on every keystroke, which is what you want for live search or character counters. change fires once the field loses focus.

Why does my listener fire twice?

Usually the code that attaches it runs more than once. Attach listeners at setup, not inside a function you call repeatedly.

Should I use onclick in the HTML?

You will see <button onclick="doThing()"> in older tutorials. It works, but it mixes behaviour into your markup and only allows one handler. Prefer addEventListener.

Where to go next#

Next lessonJavaScript async and await explained

Keep reading

Keep going — pick your next guide

The fastest way to improve is to read one guide, then build the thing it describes. Start with the basics, or jump straight to a project.

Ask a question or share what worked

Your email address will not be published. Required fields are marked *