Topic 8: JavaScript Events
📖 7 min read · 🎯 Advanced · 🧭 Prerequisites: recreate-task-external-css, tags-list
Why this matters
Up until now, every page you've built just sits there — it looks nice, but nothing happens when you click a button or type in a box. That's a static page, and users expect more. JavaScript events are what change that. An event is simply the browser noticing something — a click, a keypress, a mouse hover — and your code deciding what to do about it. Once you wire these up, your UI stops being a picture and starts being an experience. This lesson is where your designs finally start talking back.
What You'll Learn
- Understand what JavaScript events are and how the browser generates them
- Attach and remove event listeners with
addEventListenerandremoveEventListener - Work with the event object to read type, target, and key information
- Handle the most common event types:
click,mouseover,mouseout, andkeydown - Apply event delegation to manage many elements with a single listener
The Analogy
Think of a building's security desk. The guard (your event listener) sits at the entrance waiting — they're not doing anything until someone walks through the door. When a visitor arrives (an event fires), the guard checks their badge (the event object), reads the visitor's name and purpose (event.type, event.target), and calls the right department (the event handler function). You could station a guard at every single office door, or — smartly — you could use one guard at the lobby to handle everyone who enters: that's event delegation. The building runs the same way regardless; the difference is how efficiently you've staffed it.
Chapter 1: What Are JavaScript Events?
A JavaScript event is any action or occurrence that the browser detects and can report to your code. Events are the bridge between the static HTML the browser renders and the dynamic behavior users expect.
Common event triggers include:
- Clicking a button
- Hovering the mouse pointer over an element
- Moving the mouse away from an element
- Submitting a form
- Pressing a key down on the keyboard
- Releasing a key
- A web page finishing its initial load
When one of these things happens, the browser creates an event object that packages up everything your code might want to know about that moment, then delivers it to whichever listeners you've registered.
Chapter 2: Event Handling
An event listener waits for a specific event on a specific element. An event handler is the function that runs when the event fires. You register both together using addEventListener.
Adding Event Listeners
element.addEventListener(eventType, handlerFunction) is the standard, preferred approach. It keeps your JavaScript out of your HTML, and it lets you attach multiple listeners to the same element.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Event Handling Example</title>
</head>
<body>
<h1>Welcome to Vizag</h1>
<button id="greetButton">Click Me</button>
<script>
// Select the button element
const button = document.getElementById('greetButton');
// Add an event listener to the button
button.addEventListener('click', function() {
alert('Hello, Vizag!');
});
</script>
</body>
</html>
When the user clicks #greetButton, the browser sees the click event, finds the listener, and runs the anonymous function — displaying the alert.
Chapter 3: Common Event Types
Click Event
The click event fires when the user clicks an element (mouse button pressed and released on the same target).
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Click Event Example</title>
</head>
<body>
<button id="clickButton">Click Me</button>
<script>
const clickButton = document.getElementById('clickButton');
clickButton.addEventListener('click', function() {
console.log('Button was clicked!');
});
</script>
</body>
</html>
Open the browser console and click the button — you'll see Button was clicked! appear each time.
Mouseover and Mouseout Events
mouseover fires when the pointer enters an element's area; mouseout fires when it leaves. Together they create hover effects controlled entirely by JavaScript.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Mouseover Event Example</title>
</head>
<body>
<div id="hoverDiv" style="width: 200px; height: 200px; background-color: lightblue;">
Hover over me
</div>
<script>
const hoverDiv = document.getElementById('hoverDiv');
hoverDiv.addEventListener('mouseover', function() {
hoverDiv.style.backgroundColor = 'lightgreen';
});
hoverDiv.addEventListener('mouseout', function() {
hoverDiv.style.backgroundColor = 'lightblue';
});
</script>
</body>
</html>
The box switches from lightblue to lightgreen on hover, and snaps back on mouseout.
Keydown Event
keydown fires the instant a key is pressed, before any character is inserted into an input. The event object's key property tells you exactly which key was pressed.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Keydown Event Example</title>
</head>
<body>
<input type="text" id="textInput" placeholder="Type something...">
<script>
const textInput = document.getElementById('textInput');
textInput.addEventListener('keydown', function(event) {
console.log('Key pressed:', event.key);
});
</script>
</body>
</html>
Type into the input and watch the console — every key name (a, Enter, Backspace, ArrowLeft) prints immediately on press.
Chapter 4: The Event Object
Every event handler automatically receives an event object as its first argument. This object is created by the browser at the moment the event fires and carries metadata about what happened.
Key properties on the event object:
event.type— the event name as a string, e.g."click"or"keydown"event.target— the DOM element that was the original source of the eventevent.target.textContent— the visible text of that elementevent.key— (keyboard events only) which key was pressed
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Event Object Example</title>
</head>
<body>
<button id="eventButton">Click Me</button>
<script>
const eventButton = document.getElementById('eventButton');
eventButton.addEventListener('click', function(event) {
console.log('Event type:', event.type);
console.log('Button text:', event.target.textContent);
});
</script>
</body>
</html>
Clicking the button logs:
Event type: click
Button text: Click Me
Reading event.target instead of hard-coding the element reference is especially powerful inside delegated listeners, where the target changes depending on which child was clicked.
Chapter 5: Removing Event Listeners
Use removeEventListener to detach a handler once you no longer need it — for example, a one-shot action that should only fire once, or cleanup when a component is torn down.
The handler must be a named function — you cannot remove an anonymous function because each function expression creates a new reference, and removeEventListener needs the exact same reference that was passed to addEventListener.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Remove Event Listener Example</title>
</head>
<body>
<button id="removeButton">Click Me</button>
<script>
const removeButton = document.getElementById('removeButton');
function handleClick() {
alert('Button was clicked!');
removeButton.removeEventListener('click', handleClick);
}
removeButton.addEventListener('click', handleClick);
</script>
</body>
</html>
The first click shows the alert and immediately unregisters itself. Subsequent clicks do nothing — the listener is gone. This pattern is also available as { once: true } in the options argument of addEventListener, but explicit removeEventListener gives you more control over timing.
Chapter 6: Event Delegation
Attaching a listener to every list item — especially a list that grows dynamically — is expensive and fragile. Event delegation solves this by placing a single listener on a common ancestor and inspecting event.target to determine which child was actually clicked.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Event Delegation Example</title>
</head>
<body>
<ul id="itemList">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
<script>
const itemList = document.getElementById('itemList');
itemList.addEventListener('click', function(event) {
if (event.target.tagName === 'LI') {
console.log('List item clicked:', event.target.textContent);
}
});
</script>
</body>
</html>
One listener on #itemList catches clicks from all three <li> elements — and any <li> items added to the list later will automatically work too, because the listener lives on the parent, not the children. The tagName === 'LI' guard prevents the handler from firing when the user clicks the <ul> padding area between items.
flowchart TD
User["User clicks <li>Item 2</li>"] --> Event["Browser creates click event object"]
Event --> Bubble["Event bubbles up DOM tree"]
Bubble --> UL["#itemList listener fires"]
UL --> Check{"event.target.tagName === 'LI'?"}
Check -- Yes --> Log["console.log(event.target.textContent)"]
Check -- No --> Ignore["Handler exits silently"]
🧪 Try It Yourself
Task: Build a simple color-switcher panel.
Create an HTML page with four <button> elements, each labeled with a color name (Red, Blue, Green, Purple). Use event delegation — a single listener on their parent <div> — so that clicking any button changes the background-color of a target <div id="canvas"> to that button's label text (lowercased).
Success criterion: Clicking "Blue" turns the canvas blue; clicking "Red" turns it red — with only one addEventListener call in your entire script.
Starter snippet:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Color Switcher</title>
<style>
#canvas { width: 300px; height: 200px; background-color: lightgray; margin-top: 1rem; }
</style>
</head>
<body>
<div id="controls">
<button>Red</button>
<button>Blue</button>
<button>Green</button>
<button>Purple</button>
</div>
<div id="canvas"></div>
<script>
const controls = document.getElementById('controls');
const canvas = document.getElementById('canvas');
controls.addEventListener('click', function(event) {
// YOUR CODE HERE
// Hint: check event.target.tagName and use event.target.textContent
});
</script>
</body>
</html>
🔍 Checkpoint Quiz
Q1. What is the difference between an event listener and an event handler?
A) They are the same thing — both terms describe the function that runs.
B) An event listener watches for a specific event; an event handler is the function that executes when it fires.
C) An event listener runs once; an event handler runs every time.
D) An event handler is attached with on-attributes in HTML; an event listener can only be attached in CSS.
Q2. Given this snippet, what is logged when you click the button?
<button id="btn">Submit</button>
<script>
document.getElementById('btn').addEventListener('click', function(event) {
console.log(event.type, event.target.textContent);
});
</script>
A) click Submit
B) button Submit
C) click btn
D) undefined Submit
Q3. Why does removeEventListener fail when given an anonymous function?
A) Anonymous functions are not valid JavaScript.
B) removeEventListener only works on keyboard events.
C) Each anonymous function expression creates a unique reference; removeEventListener needs the identical reference that was passed to addEventListener.
D) You must call removeEventListener before addEventListener.
Q4. You have a <ul> that will have list items added dynamically via JavaScript after page load. Which approach correctly handles clicks on both existing and future <li> elements?
A) Loop over all <li> elements on DOMContentLoaded and attach a listener to each.
B) Attach a click listener to the <ul> and check event.target.tagName === 'LI' inside the handler.
C) Use inline onclick attributes on every <li> in the HTML.
D) Attach a listener to document.body and check event.target.id.
A1. B — The listener is the watcher registered via addEventListener; the handler is the callback function it calls when the event fires. They work together but are distinct concepts.
A2. A — event.type is the string "click" and event.target.textContent is "Submit", so the log reads click Submit.
A3. C — Every function expression produces a new object with its own reference. Since removeEventListener requires an exact reference match, an anonymous function defined inline can never be matched and removed.
A4. B — Event delegation on the parent <ul> catches bubbled events from all <li> children, including ones added after the listener was registered. Options A and C only cover elements present at the time of setup.
🪞 Recap
- JavaScript events are browser-generated signals that fire in response to user actions (clicks, keypresses, mouse movement) or page lifecycle changes.
addEventListener(type, handler)attaches a listener; always prefer it over inlineonclickattributes to keep JS and HTML separate.- The event object passed to every handler exposes
type,target,key, and more — use these properties instead of hard-coding element references. removeEventListenerdetaches a handler, but only works when given the same named function reference that was originally registered.- Event delegation — one listener on a parent, filtering by
event.target— is more efficient and handles dynamically added children automatically.
📚 Further Reading
- MDN: Introduction to events — the authoritative guide to event fundamentals in the browser
- MDN: EventTarget.addEventListener() — full parameter reference including the
optionsobject and{ once: true } - MDN: Event delegation — deeper explanation of bubbling and delegation patterns
- javascript.info: Introduction to browser events — practical, example-rich walkthrough of the event model
- ⬅️ Previous: Tags List
- ➡️ Next: Tags List