Skip to content
Topic 3 of 5
Theory

Events

The page reacts to actions

Everything interactive on websites — buttons, menus, search fields, games — works the same way: the code subscribes to an event ("when this button is clicked…") and says which function to call then. The code itself doesn't wait for anything: the program ends, and the handler function fires later, when the event happens.

addEventListener

const btn = document.querySelector("#hello");

btn.addEventListener("click", () => {
  console.log("The button was clicked!");
});

The first argument is the event name, the second is the handler function. You don't call it yourself (no ()): the browser will call it on every click. You can subscribe as many times as you like — all handlers will fire in order.

Common events:

Event When
click a mouse click or a tap
input the field's value changed (every letter)
change the field was changed and left; a choice in select, a checkbox
submit a form is submitted (Enter or a button)
keydown / keyup a key is pressed / released
mouseenter / mouseleave the mouse enters / leaves an element
focus / blur a field gets / loses focus

You'll also see an older way — btn.onclick = () => {...}. An element can have only one such function, a new one overwrites the old one, so addEventListener is better.

State between events

A handler is called many times, and data between calls is stored in a variable outside the handler:

let likes = 0;
const likeBtn = document.querySelector("#like");
likeBtn.addEventListener("click", () => {
  likes++;
  likeBtn.textContent = `♥ ${likes}`;
});

If you declared let likes = 0 inside the arrow function, the count would start over on every click.

The event object

The browser passes an event object with details to the handler — it's usually called e or event:

document.querySelector("#box").addEventListener("click", (e) => {
  console.log(e.type);           // "click"
  console.log(e.target);         // the element that was clicked
  console.log(e.clientX, e.clientY);  // mouse coordinates in the window
});

e.target is the element where the event happened. This will come in handy in the next topic, when one handler serves many buttons.

Text input

const search = document.querySelector("#search");
search.addEventListener("input", () => {
  console.log("Searching:", search.value);
});

input fires on every character — that's how "live" search and character counters are made. change fires when the user has finished and left the field; for <select> and checkboxes it fires right when a choice is made.

Keyboard

Key presses are listened for on document (or on an input field). Which key it was is in e.key:

document.addEventListener("keydown", (e) => {
  if (e.key === "Enter") console.log("Enter");
  if (e.key === "ArrowUp") console.log("Arrow up");
  if (e.key === " ") console.log("Space");
  if (e.ctrlKey && e.key === "s") console.log("Ctrl+S");
});

Names: letters — "a", "B"; arrows — "ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown"; "Enter", "Escape", "Shift", " " (space).

Cancelling the browser's action

Some events have a default action: a link takes you to another page, a form reloads the page, the space bar scrolls it. e.preventDefault() cancels it:

document.querySelector("a.no-go").addEventListener("click", (e) => {
  e.preventDefault();
  console.log("Not going anywhere");
});

Unsubscribing

To make a handler stop firing, remove it with removeEventListener — with the very same function, so you need to keep it in a variable:

const onClick = () => console.log("click");
btn.addEventListener("click", onClick);
btn.removeEventListener("click", onClick);

// Or right away: fire only once
btn.addEventListener("click", () => console.log("first click"), { once: true });

Summary

  • el.addEventListener("event", function) — subscribing; we pass the function, we don't call it.
  • Data between events lives in variables outside the handler.
  • e.target — where it happened, e.key — which key, e.preventDefault() — cancel the browser's action.
  • input — every change of a field, change — a finished change, keydown — a key press.

Click Counter

Easy+10 XP

Make every click on the #plus button increase the number in #count by 1.

click → 1, click → 2, click → 3

Connect the connector to solve tasks

Task code runs on your own computer — faster and more reliable than in the browser. This needs the free CodeWithMe connector app. You only connect it once.

Looking for the connector on this computer…

  1. 1
    Download the connector for your system (Windows, macOS or Linux).Download the connectorOn the download page pick the file with your system in its name, e.g. windows-amd64.
  2. 2Run it and choose a folder for your solutions. It will install Python and Node.js there by itself when needed.
  3. 3
    Enter below the 6-digit code shown in the connector window (“Code for CodeWithMe”). If the browser asks about local network access — allow it.

The connector is open source (on GitHub), works only on your computer and runs code only after you enter the pairing code.