Interactive pages wait for something to happen, such as a click, a key press or a form being submitted, and then react. Those happenings are called events, and addEventListener is how you tell JavaScript: "when this happens to that element, run this function".
Events connect everything you've learned so far. You select an element, listen for an event on it, and when the event fires, your function changes the DOM. Almost every interactive feature on the web follows that same three-step pattern.
How addEventListener works
button.addEventListener("click", () => {
console.log("Clicked!");
});- The element to listen on.
- The event name, as a string without an "on" prefix.
- A function to run, called the handler or listener.
The function doesn't run when this line runs. It runs later, every time the event happens. An element can have several listeners for the same event, and they all run.
Common JavaScript events
| Event | Fires when |
|---|---|
click | An element is clicked or tapped (or a button is activated with Enter or Space) |
input | The value of a field changes, on every keystroke |
change | A select, checkbox or input's value is committed |
submit | A form is submitted |
keydown | A key is pressed |
mouseenter / mouseleave | The pointer moves onto or off an element |
focus / blur | An element gains or loses focus |
DOMContentLoaded | The HTML has been fully read |
For forms, listen for submit on the form rather than click on the button. submit also fires when someone presses Enter in a field.
The event object
Handlers receive an event object with details about what happened:
event.targetis the element the event happened on.event.keytells you which key was pressed, for keyboard events.event.preventDefault()stops the browser's default action, such as a form reloading the page or a link opening a new address.
You'll call preventDefault() in almost every form submit handler, so that you can check and process the data with JavaScript instead of reloading the page.
Event delegation
Events bubble up from the element where they happened through each of its parents. So instead of adding a listener to 100 list items, add one listener to the list and use event.target.closest("li") to work out which item was clicked. This also works for items added to the list later, which individual listeners wouldn't cover.
JavaScript Events Syntax
Events
el.addEventListener("click", handler);
input.addEventListener("input", (e) => console.log(e.target.value));
form.addEventListener("submit", (e) => {
e.preventDefault();
});
list.addEventListener("click", (e) => {
const item = e.target.closest("li");
});JavaScript Events Summary
- Events are things that happen on the page, such as clicks and key presses.
addEventListener(eventName, handler)runs a function each time the event fires.- Listen for
submiton forms and callevent.preventDefault()to stop a reload. event.targettells you which element the event happened on.- Event delegation uses one listener on a parent to handle many children.
JavaScript Events Examples
Each example runs in the page. Edit the code and press Run to see what changes.
A click counter
<button id="like">❤️ Like</button>
<span id="count">0</span> likesconst likeBtn = document.querySelector("#like");
const countEl = document.querySelector("#count");
let likes = 0;
likeBtn.addEventListener("click", () => {
likes++;
countEl.textContent = likes;
console.log("Likes:", likes);
});Line-by-line explanation
- Line 3The state: how many likes so far.
- Line 5Listen for clicks on the button.
- Lines 6 to 8Each click updates the state, then the page.
Live input and form submit
Type in the box, then press Send.
<form id="form">
<label for="msg">Message</label>
<input id="msg" maxlength="40" autocomplete="off">
<small id="chars">0 / 40</small>
<button>Send</button>
</form>
<ul id="sent"></ul>const form = document.querySelector("#form");
const input = document.querySelector("#msg");
const chars = document.querySelector("#chars");
const sent = document.querySelector("#sent");
input.addEventListener("input", (event) => {
chars.textContent = `${event.target.value.length} / 40`;
});
form.addEventListener("submit", (event) => {
event.preventDefault();
const text = input.value.trim();
if (!text) return;
const li = document.createElement("li");
li.textContent = text;
sent.append(li);
input.value = "";
chars.textContent = "0 / 40";
});Line-by-line explanation
- Lines 6 to 8
inputfires on every keystroke, which makes it ideal for live counters and search. - Line 10Listen to the form's submit event (it also fires when pressing Enter).
- Line 11Stop the page from reloading.
- Line 13Ignore empty messages.
Keyboard and event delegation
Click any colour chip, or press keys 1 to 3.
<div id="chips">
<button data-color="#f0592b">Orange</button>
<button data-color="#4467ff">Blue</button>
<button data-color="#17a865">Green</button>
</div>
<div id="swatch" style="height:60px;margin-top:10px;border-radius:10px;background:#eee"></div>const chips = document.querySelector("#chips");
const swatch = document.querySelector("#swatch");
chips.addEventListener("click", (event) => {
const button = event.target.closest("button");
if (!button) return;
swatch.style.background = button.dataset.color;
console.log("Picked", button.textContent);
});
document.addEventListener("keydown", (event) => {
const index = Number(event.key) - 1;
const button = chips.children[index];
if (button) button.click();
});Line-by-line explanation
- Line 4One listener on the parent handles every chip. This is delegation.
- Lines 5 to 6Find which button was clicked (or ignore clicks between buttons).
- Line 11Listen for key presses anywhere on the page.
- Line 14Pretend-click the matching button.
Common JavaScript Events Mistakes
Calling the handler immediately
button.addEventListener("click", showMenu()); // runs now, not on clickbutton.addEventListener("click", showMenu);Listening to the button instead of the form
submitButton.addEventListener("click", save); // misses Enter key, no validationform.addEventListener("submit", (e) => { e.preventDefault(); save(); });The submit event covers clicking, pressing Enter, and runs after built-in HTML validation.
Using onclick attributes everywhere
<button onclick="doThing()">Go</button>document.querySelector("#go").addEventListener("click", doThing);addEventListener keeps JavaScript out of your HTML and allows several listeners per event.
JavaScript Events in Real Projects
Events are the heartbeat of apps
Search-as-you-type uses input, games use keydown, drag-and-drop uses pointer events, infinite scroll uses scroll or observers, and every "Add to cart" is a click. In frameworks you'll write onClick={…}, but underneath it's the same event system.
JavaScript Events Exercises
Answer each one and check it instantly. If you get stuck, open the hint before the answer.
Run toggleMenu when the button is clicked.
menuButton.("", toggleMenu);
What does event.preventDefault() do in a submit handler?
Which event fires on every keystroke in a text box?
input fires whenever the value changes.Clicking the button should toggle the dark class on the box and log Dark: true the first time. Fix the bugs.
<div id="box" style="padding:20px;border:2px solid #333">Box</div>
<button id="toggle">Toggle</button>
<style>.dark { background: #15161b; color: white; }</style>const box = document.querySelector("#box");
const toggle = document.querySelector("#toggle");
toggle.addEventListener("onclick", () => {
box.classList.toggle("dark");
console.log("Dark:", box.classList.contains("dark"));
});- Clicking toggles the dark class
- Logs "Dark: true" after a click
JavaScript Events Quiz
3 questions to check what you learned.
Which method attaches an event handler?
- el.onEvent()
- el.listen()
- el.handle()
- el.addEventListener()
What is
event.target?- The function that handles the event
- The element the event actually happened on
- The parent element
- The window
What is event delegation?
- Adding the same listener to every child
- Passing events to a server
- Putting one listener on a parent and handling events from its children
- Removing listeners automatically
JavaScript Events Challenge
Build a tip calculator
When the form is submitted (prevent the reload):
- Read the bill from
#billand the tip % from#tip(convert to numbers) - Calculate
tip = bill * percent / 100andtotal = bill + tip - Show
Tip: £7.50 · Total: £57.50in#result(usetoFixed(2))
<form id="calc">
<label>Bill £ <input id="bill" type="number" value="50"></label>
<label>Tip % <input id="tip" type="number" value="15"></label>
<button>Calculate</button>
</form>
<p id="result"></p>const calc = document.querySelector("#calc");
- Submitting shows the right result
- Works with other values
- Uses a submit listener