CodingNic

Events

Exercises

Events 40 min read

Exercises

Objectives

This chapter introduces no new concepts. It’s a chance to practice everything from this module: listening for events, mouse/keyboard/form events, bubbling and capturing, delegation, and custom events.

All exercises use this starting HTML:

text
<div id="panel">
  <button id="toggleBtn">Toggle</button>
  <ul id="list">
    <li class="entry">First</li>
    <li class="entry">Second</li>
  </ul>
  <form id="entryForm">
    <input type="text" name="entry" value="">
    <button type="submit">Add</button>
  </form>
</div>

Exercises

  1. Select #toggleBtn and add a click listener that logs "Toggled". Click it. Check: it logs Toggled.

  2. Inside that same listener, also log event.type. Check: it logs click.

  3. Store a named function in a variable, attach it to #toggleBtn for click, click once, then call .removeEventListener() with that same function and click again. Check: a counter incremented inside the function equals 1, not 2.

  4. Add mouseover and mouseout listeners to #panel that set a variable to true and false. Dispatch a mouseover, then a mouseout. Check: the variable is true right after the first, false right after the second.

  5. Select the text input inside #entryForm with entryForm.elements["entry"], and add a keydown listener that logs event.key. Dispatch a keydown with key "a". Check: it logs a.

  6. Add a submit listener to #entryForm that calls event.preventDefault() and logs the value of the entry field. Set the field’s value to "Third", then submit the form. Check: it logs Third, and event.defaultPrevented is true.

  7. Add click listeners to #panel and #list that each push their own id ("panel" or "list") to an array. Click the first .entry with document.querySelector(".entry").click(). Check: the array is ["list", "panel"], in that order, since the click bubbles from the target upward.

  8. Add event.stopPropagation() inside #list’s listener from the previous exercise. Click the first .entry again. Check: #list’s listener still runs, but #panel’s listener does not.

  9. Add one click listener to #list that uses event.target.closest(".entry") to find the clicked entry and log its .textContent. Append a new <li class="entry">Fourth</li> to #list after attaching the listener, then click it. Check: it logs Fourth, proving the one listener handles an item that didn’t exist when it was attached.

  10. Add a listener for a custom event named "cleared" on #list that logs event.detail.count. Dispatch it with new CustomEvent("cleared", { detail: { count: 2 } }). Check: it logs 2.

  11. Add a click listener to #panel with { capture: true } that pushes "panel-capture" to an array, and a normal click listener to #toggleBtn that pushes "toggle-bubble". Click #toggleBtn. Check: the array is ["panel-capture", "toggle-bubble"], capture fires first.

  12. Add a listener for a custom event named "cleared-bubbling" on #panel. Dispatch it from #list with { detail: { count: 5 }, bubbles: true }. Check: #panel’s listener still receives it, with event.detail.count equal to 5.

Recap

You can now attach and remove listeners, handle mouse, keyboard, and form events, reason about bubbling and capturing, delegate events to a parent, and dispatch your own custom events. That’s the full toolkit for responding to a user. Next is putting all of it into one real project.

Next lesson: the mini project, a working to-do list built entirely from the DOM and events.