Week 5: Events & Interaction

To Do This Week:

Assignments:

Make sure your numbered logic steps are commented at the top of your <script> tag.

Read (Optional!): Chapters from Eloquent JavaScript:

Upcoming Assignments


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

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="").

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

Keyboard events

Form & input events

Window & document events


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:

// 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
  }
});

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:

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.

Common bugs to watch for:


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

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.

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

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:

Some starting ideas