Week 5: Events & Interaction
To Do This Week:
Assignments:
- Clickable Page (5%) is (Due 9/30)
Make sure your numbered logic steps are commented at the top of your <script> tag.
Read (Optional!): Chapters from Eloquent JavaScript:
- Handling Events
- The Document Object Model (review)
Upcoming Assignments
- Slider/Menu Site (5%) (Due Week 7 — 10/7)
Module Notes
Last week we learned to select DOM elements with a "click" and change their CSS values. This week expands on events — the moments a user (or the browser) does something, and the code we run in response.
An event is a message. A click, a keypress, a mouse moving, a page finishing loading, a form being submitted — each one is the browser saying "this just happened." Your job is to listen for the ones you care about and respond.
The pattern is always the same three parts:
target.addEventListener("eventType", handlerFunction);
// ↑ what to watch ↑ what happened ↑ what to do about it
In-class Exercise:
Event Playground: Clicks, Keys, Hovers & the Event Object- listen for different event types
- read the
eventobject - use
event.target - keyboard interaction
- mouse position with
e.clientX/e.clientY - live form input and
preventDefault() - event delegation (one listener for many elements)
stopPropagation()(a close button inside a clickable card)
1. addEventListener
This is the modern, preferred way to respond to events. You can attach many listeners to the same element, and it keeps your JavaScript separate from your HTML (onclick="").
-
element.addEventListener("click", handler)
Runshandlerevery time the event fires. -
element.removeEventListener("click", handler)
Stops listening. (The handler must be a named function to remove it.)
The handler can be written inline or as a named function. A named function is easier to read, reuse, and debug:
// inline (anonymous) function
button.addEventListener("click", function () {
console.log("clicked");
});
// named function — same result, cleaner
function handleClick() {
console.log("clicked");
}
button.addEventListener("click", handleClick);
Watch out: write handleClick, not handleClick(). With the parentheses you call the function immediately and hand its result to the listener. Without them, you hand over the function itself, to be called later when the event fires.
2. Common Event Types
Mouse events
"click"// a full press-and-release on an element"dblclick"// double-click"mousedown"/"mouseup"// the press and the release, separately"mouseenter"/"mouseleave"// pointer enters or leaves an element (these do not bubble — see section 5)"mousemove"// fires constantly as the pointer moves — use with care
Keyboard events
"keydown"// a key is pressed down (fires repeatedly if held)"keyup"// a key is released
Form & input events
"input"// fires on every change to a text field (great for live updates)"change"// fires when a field loses focus after changing (good for checkboxes, selects)"submit"// a form is submitted (usually paired withpreventDefault())
Window & document events
"DOMContentLoaded"// the HTML is fully parsed — safe to select elements"load"// everything (images, etc.) has finished loading"scroll"// the user scrolls"resize"// the window changes size
3. The Event Object
When an event fires, the browser hands your function an event object full of details about what just happened. Catch it by naming a parameter — e or event by convention.
button.addEventListener("click", function (e) {
console.log(e); // the whole event object — explore it in the Console
console.log(e.type); // "click"
console.log(e.target); // the exact element that was clicked
});
Useful properties:
-
e.target
The element the event actually happened on. Essential for delegation (section 5). -
e.currentTarget
The element the listener is attached to (not always the same as target). -
e.type
The name of the event, e.g."click". -
e.key
For keyboard events — which key, e.g."Enter","a","ArrowLeft". -
e.clientX/e.clientY
For mouse events — the pointer's coordinates on screen.
// Demo: which key did the user press?
document.addEventListener("keydown", function (e) {
console.log("You pressed:", e.key);
if (e.key === "Enter") {
console.log("Enter was pressed!");
}
});
// Demo: listen for the "w" key
document.addEventListener("keydown", function (e) {
if (e.key === "w") {
console.log("W was pressed!");
}
});
4. preventDefault()
Some elements have built-in browser behavior: a form reloads the page when submitted, a link navigates away. e.preventDefault() stops that default so your JavaScript can take over instead.
// Demo: handle a form without the page reloading
const form = document.querySelector("#myForm");
form.addEventListener("submit", function (e) {
e.preventDefault(); // stop the page reload
const value = document.querySelector("#name").value;
console.log("Submitted name:", value);
});
preventDefault() stops the browser's default action. It does not stop the event from bubbling. That's a different method, stopPropagation() (section 6).
5. Event Delegation
Imagine 20 buttons, or a list where new items keep getting added. Attaching a listener to each one is tedious — and brand-new elements won't have listeners at all.
Event delegation solves this with one idea: events bubble up. Most events start on the element you interact with (the target) and then travel up through every ancestor — parent, grandparent, all the way to document. Any ancestor with a matching listener gets a turn. So you put a single listener on the parent, then use e.target to find out which child was actually clicked.
// One listener on the container handles all current AND future buttons.
const list = document.querySelector("#list");
list.addEventListener("click", function (e) {
// did the click land on a button?
if (e.target.matches("button")) {
console.log("You clicked:", e.target.textContent);
e.target.remove(); // for example, delete that item
}
});
-
element.matches("selector")
Returnstrueif the element matches a CSS selector. Same selectors asquerySelector. -
element.remove()
Deletes the element from the page.
Not every event bubbles. mouseenter and mouseleave fire only on the element itself. (Their bubbling cousins are mouseover and mouseout.)
Why this matters: a To-Do list, a photo gallery, a card grid — anything where items appear and disappear — is far cleaner with delegation than with a listener per item.
6. stopPropagation()
Bubbling is usually what you want. But sometimes a click on a child should not reach its parent. A common case in interactive work: a card that opens when you click it, with an × in the corner that closes it.
const card = document.querySelector("#card");
const closeBtn = document.querySelector("#card .close");
// clicking anywhere on the card opens it
card.addEventListener("click", function () {
card.classList.add("open");
});
// the × is INSIDE the card, so its click bubbles up to the card
closeBtn.addEventListener("click", function (e) {
e.stopPropagation(); // end the event here
card.classList.remove("open");
});
Without stopPropagation(), one click on the × does two things: the × handler closes the card, then the click bubbles up and the card's handler opens it again. The × looks broken. e.stopPropagation() keeps the event from traveling any further up the tree.
7. Running Code After the Page Loads
If your <script> runs before the elements exist, your selections return null. Two fixes:
- Put the
<script>at the bottom of the body (simplest). - Or wrap your code so it waits:
document.addEventListener("DOMContentLoaded", function () {
// safe to select and wire up elements here
});
Debugging Events in the Console
Events are invisible until you make them speak. The Console is how you confirm an event fired and see what it carried.
console.log("handler ran")// did my listener fire at all?console.log(e.target)// what element triggered it?console.log(e.key)// which key was pressed?console.dir(e)// expand the full event object to explore its properties
Common bugs to watch for:
- Passing
handler()instead ofhandlertoaddEventListener. - Listening on an element that is
nullbecause it wasn't selected correctly (often a missing#or.inquerySelector). - Setting up listeners before the HTML exists (script too high on the page).
- Expecting
e.targetto be the container when it's actually the child that was clicked. - Forgetting
e.preventDefault()on a form and watching the page reload. - A click on a child also triggering its parent's listener. If you don't want that, use
e.stopPropagation().
Workshop (Thursday)
We'll keep building fluency by working from logic steps and debugging together. Come with your Clickable Page idea- sketch it and start the logic steps
- Start from plain-English logic steps, then translate one step at a time.
- Use Google and documentation (MDN, W3Schools) to look up specific syntax.
- Use AI to explain a specific event, property, or bug — not to generate whole solutions.
- Check the Console. Confirm each listener fires before moving on.
Example: logic steps at the top of your script
Write the steps in plain English before any code. Each step should be one small action you can translate into a line or two of JavaScript.
<script>
/*
LOGIC STEPS:
1. Select the button and the box.
2. Listen for a click on the button.
3. When the button is clicked, change the box's background color.
4. Also change the button's text to say "Clicked!"
*/
// your code goes here, one step at a time
</script>
In-class Demo and Templates
Open each file in the browser and in your code editor.
1. DOM Playground: Buttons, Boxes & Menus
Six small demos. Each one uses a button to change one thing. The only CSS in the file is the CSS that JavaScript changes.
2. Clickable Page Template (empty starter)
A blank starter page to build your project on. It has no JavaScript and no animation. Every element you might click or change already has an id.
3. Clickable Page Demo (the same template, with changes)
The template with one change attached to each clickable element. Compare it with the empty starter.
4. Event Playground: Clicks, Keys, Hovers & the Event Object
All the event types we discussed in one file. Click, hover, type, and watch the Console to see what the event object carries.
Ways to expand your project idea
These are suggestions, not requirements — take on what you feel ready for. Each level uses a little more JavaScript than the one above it. The Circles Animation project from Week 1 does all of them at once.
- Events and animation. Interactive design where clicks, hovers, and keys trigger CSS transitions and animations. The JavaScript adds and removes classes; the CSS does the moving.
- Add stored data. Keep a set of values — quotes, colors, image names, words — in an array, then pull from it and insert onto the page. Your content now lives in one place instead of being scattered through the HTML.
-
Add randomness. Use
Math.random()to generate values — a color, a position, a size, a pick from your array — so the page is never quite the same twice. -
Add conditionals. Use
ifstatements to decide what happens when. For example, if the user clicks a button, do one thing; if they click it again, do something else. -
Add timing. Let the page act on its own:
setTimeout()runs something once after a delay, andsetInterval()repeats it every so many milliseconds. A delay between steps can turn a single change into a small performance.
Add a loop or a sequence. Use a loop to make many elements at once, or
setInterval() to keep a sequence running. Because the values are random, it repeats without ever repeating exactly.
Whatever level you choose, wrap the behavior in functions you can call more than once, and use conditionals to decide what happens when. Those two show up at every level.
Project Introduction: Clickable Page (5%) DUE: Week 6 — 9/30
Build a single web page that responds to user interaction. Clicking elements should trigger visible changes such as content updates, CSS transitions, color or style changes, animated movement, or the appearance and disappearance of elements.
You may start from the Clickable Page Template or build your own layout.
Plan the logic in plain English before writing code. Your grade will emphasize clear logic, working JavaScript, purposeful interaction, and a coherent visual design.
Minimum Requirements
- At least three clickable elements
- At least three visible changes produced with JavaScript
- DOM selection and manipulation
- At least one CSS transition or animated change
- Numbered logic steps in a comment before the script
- No AI-generated code
Logic Steps (required)
At the very top of your <script> tag, before any code, write your numbered logic steps as a commented list. Example:
/*
1. Select the button and the box.
2. When the button is clicked, run a function.
3. Inside the function, toggle the "active" class on the box.
4. The .active class in CSS changes color and size with a transition.
5. Also change the button's text to say "On" or "Off".
*/
This comment block is part of your grade. Without it, the project is considered incomplete.
Workshop (Next Monday)
Bring your idea and a first draft of your logic steps. We'll work them out together and start coding. During the workshop you may:
- Use Google and documentation (MDN, W3Schools) to look up specific syntax.
- Use AI to explain a specific step or concept — not to generate your project code.
- Use the Console constantly to check selections and debug.
Some starting ideas
- Mood switcher: buttons change the page's colors, fonts, and a headline.
- Reveal cards: click a card to flip it or reveal hidden text. I will demo how to flip cards next week.
- Toggle gallery: buttons show/hide groups of images.
- Slide-out menu: a button slides a nav panel in and out.
- Weird art toy: clicks move, grow, recolor, or multiply elements. The stranger the better.