Events & State

The Course
•
4 min read

A program that runs once can produce a report. An interactive page also responds later, when a person clicks, types, or submits a form. Those actions create events. addEventListener("click", callback) registers a function to run for each click. Pass the function itself; writing callback() would call it immediately instead.

Keep state, the application’s current data, separate from rendering, the code that displays it. For a counter: state is a number; an event changes the number; render writes the number to textContent. Do not use the visible label as the only storage for the count.

Use an actual button, not a clickable paragraph. Buttons support keyboard activation automatically. Give the output an aria-live attribute so assistive technology can announce updates. These small choices make the same interaction available to more people.

Read the button and listener together

In the lab, <button id="add" type="button">Add 5 minutes</button> creates a button. Its id lets the script find it; type=button gives it a plain action rather than form submission.

The script defines addFive, then registers it with document.querySelector("#add").addEventListener("click", addFive). The browser keeps that function and calls it later for each click. The final render() at the bottom runs immediately to show the initial zero. That gives three separate jobs: find the button, register the future action, and display the starting state.

aria-live="polite" is an HTML attribute on the output paragraph. It asks screen readers to announce changed text when they can do so without interrupting the user.

Predict before running

The console example models two clicks by calling a function twice. In the webpage lab below, the browser calls the handler in response to the real button. What is the final value?

Predict, then run JavaScript
let minutes = 0;

function addFive() {
  minutes = minutes + 5;
}

addFive();
addFive();
console.log(minutes);
Check your prediction
10

Trace each statement in order. If your prediction differed, describe the first place your mental model and the result diverged before trying again.

State changes first, display follows

A click is an event: the browser calls your listener when it happens. Pass a function to addEventListener; do not call it while registering. Keep a number as state and render it after every change. If you only change visible text, later code may still read an old state value. Predict three clicks and one reset before trying the browser lab.

State changes first, display follows JavaScript
let count = 0;

function increment() {
  count += 1;
}

function reset() {
  count = 0;
}

increment();
increment();
reset();
increment();
console.log(count);
Check your prediction
1

These functions simulate the same state transitions without a browser. The DOM listener can call them and then update textContent.

Your turn

Exercise

Events & State: practise

Model a reset button: start at 20, write reset() that sets minutes to zero, call it, and print 0. Then add a real reset button to the webpage lab below.

Your working space JavaScript
let minutes = 20;
// Define reset, call it, then print minutes.
Hint 1: the idea

A reset is an assignment to the existing state, not another local variable.

Hint 2: a first step

Use minutes = 0 inside the function; do not write let minutes there.

Show one solution
let minutes = 20;

function reset() {
  minutes = 0;
}

reset();
console.log(minutes);
0

In the browser version, call render after changing state. Try clicking Add 5 twice, Reset, then Add 5: the visible value should be 5.

What you should be able to explain

  • When does a registered listener execute?
  • What is the source of truth for the count?
  • Why should reset also update the display?

Try the webpage

Press Run webpage to preview. Each run starts fresh. Edits are not saved automatically.

Run the page and click Add 5 twice. Then add <button id="reset" type="button">Reset</button> beside the first button, outside the script tags. Inside the script, define reset to set minutes to zero and call render. Register it on the reset element with a click listener just as the lab registers addFive. Keep all JavaScript inside the script tags. Use Tab and Enter to try the buttons without a mouse.

Was this article helpful?

Your response is saved on this device.