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:
<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
-
Select
#toggleBtnand add a click listener that logs"Toggled". Click it. Check: it logsToggled. -
Inside that same listener, also log
event.type. Check: it logsclick. -
Store a named function in a variable, attach it to
#toggleBtnforclick, click once, then call.removeEventListener()with that same function and click again. Check: a counter incremented inside the function equals1, not2. -
Add
mouseoverandmouseoutlisteners to#panelthat set a variable totrueandfalse. Dispatch amouseover, then amouseout. Check: the variable istrueright after the first,falseright after the second. -
Select the text input inside
#entryFormwithentryForm.elements["entry"], and add akeydownlistener that logsevent.key. Dispatch a keydown with key"a". Check: it logsa. -
Add a
submitlistener to#entryFormthat callsevent.preventDefault()and logs the value of theentryfield. Set the field’s value to"Third", then submit the form. Check: it logsThird, andevent.defaultPreventedistrue. -
Add click listeners to
#paneland#listthat each push their own id ("panel"or"list") to an array. Click the first.entrywithdocument.querySelector(".entry").click(). Check: the array is["list", "panel"], in that order, since the click bubbles from the target upward. -
Add
event.stopPropagation()inside#list’s listener from the previous exercise. Click the first.entryagain. Check:#list’s listener still runs, but#panel’s listener does not. -
Add one click listener to
#listthat usesevent.target.closest(".entry")to find the clicked entry and log its.textContent. Append a new<li class="entry">Fourth</li>to#listafter attaching the listener, then click it. Check: it logsFourth, proving the one listener handles an item that didn’t exist when it was attached. -
Add a listener for a custom event named
"cleared"on#listthat logsevent.detail.count. Dispatch it withnew CustomEvent("cleared", { detail: { count: 2 } }). Check: it logs2. -
Add a click listener to
#panelwith{ capture: true }that pushes"panel-capture"to an array, and a normal click listener to#toggleBtnthat pushes"toggle-bubble". Click#toggleBtn. Check: the array is["panel-capture", "toggle-bubble"], capture fires first. -
Add a listener for a custom event named
"cleared-bubbling"on#panel. Dispatch it from#listwith{ detail: { count: 5 }, bubbles: true }. Check:#panel’s listener still receives it, withevent.detail.countequal to5.
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.