<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Osaro Iyoha</title>
    <description>The latest articles on DEV Community by Osaro Iyoha (@osaaroh).</description>
    <link>https://dev.to/osaaroh</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4146077%2F21819dd6-8de0-4627-ae01-5df028301f8b.jpg</url>
      <title>DEV Community: Osaro Iyoha</title>
      <link>https://dev.to/osaaroh</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/osaaroh"/>
    <language>en</language>
    <item>
      <title>JavaScript Concepts I Wish I Understood Earlier: Event Bubbling &amp; Event Delegation</title>
      <dc:creator>Osaro Iyoha</dc:creator>
      <pubDate>Sun, 27 Sep 2026 23:38:47 +0000</pubDate>
      <link>https://dev.to/osaaroh/javascript-concepts-i-wish-i-understood-earlier-event-bubbling-event-delegation-28k9</link>
      <guid>https://dev.to/osaaroh/javascript-concepts-i-wish-i-understood-earlier-event-bubbling-event-delegation-28k9</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"With AI writing the code, maybe it's time we finally understand what the code is doing."&lt;/em&gt; 😅&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The rise of AI has made writing code easier than ever. It has also made one thing increasingly important for me: &lt;strong&gt;actually understanding JavaScript.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After a year away from frontend development, I found myself coming back to JavaScript feeling more than a little disoriented, especially with the AI boom, and the temptation to just let a model generate everything for me.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fr8vic8helzyat3smjc7z.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fr8vic8helzyat3smjc7z.jpg" alt="The popular meme showing two people in the same bus but with different perspectives." width="800" height="786"&gt;&lt;/a&gt;&lt;em&gt;AI Fears vs AI Cheers.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Instead, I saw a golden opportunity to properly understand JavaScript, and decided to go back to the fundamentals. Not &lt;em&gt;"what does this syntax do?"&lt;/em&gt; fundamentals. More like:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"Why does JavaScript work this way, and how could I have written this better?"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That led me to revisit some of my old projects. And that's where I found some code from 2024 that made me think:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Past me knew JavaScript.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Past me now has some explaining to do. 😂&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is the beginning of a series about JavaScript concepts I'm learning — or relearning — and the things I wish I had understood earlier.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Event Bubbling and Event Delegation
&lt;/h2&gt;

&lt;p&gt;Let's start with something simple. Imagine you're building an FAQ section with accordion/drop down buttons for each question.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdnyda1iwrpyz4r0odn2h.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdnyda1iwrpyz4r0odn2h.jpg" alt="Image showing the FAQ section of website with dropdown to show details. This was a challenge from Frontend Mentor." width="800" height="511"&gt;&lt;/a&gt;&lt;em&gt;FAQ Accordion: Front end mentor &lt;a href="https://www.frontendmentor.io/challenges/faq-accordion-card-XlyjD0Oam" rel="noopener noreferrer"&gt;challenge&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You have five questions. Clicking the button on a question should reveal its answer, while closing any other open answer.&lt;/p&gt;

&lt;p&gt;Something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"acc"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"acc-item"&lt;/span&gt; &lt;span class="na"&gt;data-id=&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h3&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"acc-title"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Question 1&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"acc-icon-container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;+&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"acc-content hide"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Answer 1&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"acc-item"&lt;/span&gt; &lt;span class="na"&gt;data-id=&lt;/span&gt;&lt;span class="s"&gt;"2"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h3&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"acc-title"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Question 2&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"acc-icon-container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;+&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"acc-content hide"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Answer 2&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"acc-item"&lt;/span&gt; &lt;span class="na"&gt;data-id=&lt;/span&gt;&lt;span class="s"&gt;"3"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h3&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"acc-title"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Question 3&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"acc-icon-container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;+&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"acc-content hide"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Answer 3&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pretty straightforward. But the interesting part isn't the accordion. It's &lt;strong&gt;how we listen for the clicks.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  How I used to do it
&lt;/h2&gt;

&lt;p&gt;Back in 2024, I approached the problem by grabbing all the buttons, all the content, and all the headers separately:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;accordionBtns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelectorAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.acc-icon-container&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;accordionContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelectorAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.acc-content&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;accordionHeader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelectorAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.acc-title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then I added an event listener to every button:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;accordionBtns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;accordionBtns&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;hideOtherAccordionContentExceptThis&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;toggleAccordion&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;accordionContent&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At the time, this made perfect sense to me. Button #1 corresponds to content #1. Button #2 corresponds to content #2. Button #3 corresponds to content #3. So I could use the index to keep everything connected:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;accordionBtns[2]
      ↓
accordionContent[2]
      ↓
accordionHeader[2]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It worked. But there's a problem: the &lt;strong&gt;index was doing a lot of work.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;My code depended on the assumption that all these NodeLists would always have the same structure and order. That's why I was passing &lt;code&gt;x&lt;/code&gt; everywhere — into &lt;code&gt;toggleAccordion(accordionContent[x], x)&lt;/code&gt; and &lt;code&gt;hideOtherAccordionContentExceptThis(x)&lt;/code&gt;. The &lt;code&gt;x&lt;/code&gt; was essentially carrying information around because my elements didn't have a direct relationship in the JavaScript itself.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Me in 2024:&lt;/strong&gt; "Don't worry bro, index 2 knows what index 2 means."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Me in 2026:&lt;/strong&gt; "That's... not ideal." 😂&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I also had this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;currentClassList&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;currentClassList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hide&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At the time, I thought "&lt;code&gt;classList&lt;/code&gt; isn't an array, so let me convert it into one." Technically, that works. But I was solving a problem that didn't exist — &lt;code&gt;classList&lt;/code&gt; already gives us methods designed for exactly this, like &lt;code&gt;item.classList.contains("hide")&lt;/code&gt; or &lt;code&gt;item.classList.toggle("hide")&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That was another small lesson: &lt;strong&gt;before converting something into another data structure, check whether the object already has the functionality you need.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Enter Event Delegation
&lt;/h2&gt;

&lt;p&gt;When I came back to this project, I wanted to refactor it. Instead of attaching an event listener to every accordion button, I could attach &lt;strong&gt;one listener to the parent container&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;accordionList&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.acc&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;accordionList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One listener for the entire accordion. But how does the parent know which button was clicked? That's where &lt;strong&gt;event bubbling&lt;/strong&gt; comes in.&lt;/p&gt;

&lt;p&gt;When you click an element, the event doesn't necessarily stay there — it &lt;strong&gt;bubbles up through its ancestors&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.acc
  │
  └── .acc-item
        │
        └── button
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You click the button. The click happens on the button. The event then bubbles upward:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;button
  ↑
.acc-item
  ↑
.acc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So even though our event listener is attached to &lt;code&gt;accordionList&lt;/code&gt;, we can still determine what was clicked. That's the foundation of event delegation.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;code&gt;event.target&lt;/code&gt; and &lt;code&gt;.closest()&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Inside our event listener:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;accordionList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;event.target&lt;/code&gt; tells us the element where the event originated. If I click &lt;code&gt;&amp;lt;button class="acc-icon-container"&amp;gt;+&amp;lt;/button&amp;gt;&lt;/code&gt;, &lt;code&gt;event.target&lt;/code&gt; points to that button. Now we can use &lt;code&gt;.closest()&lt;/code&gt; to find our way back up:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;toggleBtn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;closest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.acc-icon-container&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;toggleBtn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// guard clause: click wasn't on a toggle button&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we move upward again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;accordionItem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;toggleBtn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;closest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.acc-item&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we have the specific accordion item containing the button that was clicked, and from there we can move back down into it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;accordionHeader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;accordionItem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.acc-title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;currentParagraph&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;accordionItem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.acc-content&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The mental model becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User clicks button
       ↓
event.target
       ↓
closest(".acc-icon-container")
       ↓
closest(".acc-item")
       ↓
querySelector(".acc-title")
querySelector(".acc-content")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or, in plain English: &lt;strong&gt;"I clicked this button. Which accordion item does it belong to? Now give me the elements inside that accordion item."&lt;/strong&gt; That's a much more natural relationship than "give me item number 3 because button number 3 was clicked."&lt;/p&gt;




&lt;h2&gt;
  
  
  The Refactored Version
&lt;/h2&gt;

&lt;p&gt;Here's where the pieces come together:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;accordionList&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.acc&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;accordionList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;toggleBtn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;closest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.acc-icon-container&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;toggleBtn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;accordionItem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;toggleBtn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;closest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.acc-item&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;accordionHeader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;accordionItem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.acc-title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;currentParagraph&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;accordionItem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.acc-content&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Reset all other accordion items&lt;/span&gt;
  &lt;span class="nx"&gt;accordionList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelectorAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.acc-item&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;accordionItem&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.acc-content&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hide&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.acc-title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bold&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.acc-icon-container&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rotate&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="c1"&gt;// Toggle current accordion&lt;/span&gt;
  &lt;span class="nx"&gt;currentParagraph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toggle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hide&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;accordionHeader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toggle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bold&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;toggleBtn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toggle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rotate&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The icon rotation can be handled with CSS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.acc-icon-container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;transition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;transform&lt;/span&gt; &lt;span class="m"&gt;0.3s&lt;/span&gt; &lt;span class="n"&gt;ease&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.acc-icon-container.rotate&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;180deg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we have one event listener on &lt;code&gt;.acc&lt;/code&gt;, asking "which button? which accordion item? which content/header/icon?" — instead of five separate listeners each hoping their index lines up with everyone else's.&lt;/p&gt;

&lt;p&gt;My old code was based on &lt;strong&gt;indexes&lt;/strong&gt;: &lt;code&gt;accordionBtns[x]&lt;/code&gt;, &lt;code&gt;accordionContent[x]&lt;/code&gt;, &lt;code&gt;accordionHeader[x]&lt;/code&gt;. My new code is based on &lt;strong&gt;relationships in the DOM&lt;/strong&gt;: &lt;code&gt;toggleBtn&lt;/code&gt; → &lt;code&gt;accordionItem&lt;/code&gt; → &lt;code&gt;accordionHeader&lt;/code&gt; / &lt;code&gt;currentParagraph&lt;/code&gt;. The second approach is easier to reason about because the DOM itself describes the relationship — each &lt;code&gt;.acc-item&lt;/code&gt; already contains everything it needs, so instead of maintaining separate arrays and hoping their indexes stay synchronized, I can start from the element I interacted with and navigate to what's related to it.&lt;/p&gt;

&lt;p&gt;There's also a small &lt;code&gt;toggle()&lt;/code&gt; lesson buried in here. Originally I was manually checking whether a class existed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;currentClassList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hide&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hide&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hide&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But JavaScript already gives us &lt;code&gt;item.classList.toggle("hide")&lt;/code&gt; — and the same idea covers &lt;code&gt;accordionHeader.classList.toggle("bold")&lt;/code&gt; and &lt;code&gt;toggleBtn.classList.toggle("rotate")&lt;/code&gt;. Instead of saying "if the class exists, remove it, otherwise add it," I'm saying &lt;strong&gt;"toggle this state."&lt;/strong&gt; Sometimes the best refactor isn't shorter code — it's code that says what you actually mean.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why This Matters Beyond a Five-Button Accordion
&lt;/h2&gt;

&lt;p&gt;You might be thinking: "Okay, but is this really necessary for five buttons?" Five event listeners aren't going to destroy your browser. The real value is the pattern, it becomes essential once you're dealing with larger or &lt;strong&gt;dynamically generated UIs&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;With individual listeners, every new button needs its own listener attached by hand. With delegation, one listener on the parent handles clicks from any child: including children that don't exist yet. If you add another accordion item later, the parent listener handles clicks on it automatically, with nothing extra to wire up.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I Actually Learned
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Events bubble.&lt;/strong&gt; A click on a child element propagates upward through its ancestors.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Event delegation lets a parent handle events for its children&lt;/strong&gt;, instead of attaching a listener to every single one.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;event.target&lt;/code&gt;&lt;/strong&gt; tells us where the event originated.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;.closest()&lt;/code&gt;&lt;/strong&gt; lets us navigate upward to the nearest matching ancestor.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;.querySelector()&lt;/code&gt;&lt;/strong&gt; lets us navigate back down from there.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DOM relationships beat parallel arrays.&lt;/strong&gt; &lt;code&gt;buttons[2] → content[2]&lt;/code&gt; is fragile; "this button → this accordion item → this content" isn't.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Check for built-in methods before reaching for a conversion&lt;/strong&gt; — &lt;code&gt;classList&lt;/code&gt; already does most of what you need.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Looking back at my 2024 code, I wouldn't call it bad code — it solved the problem, and that's worth acknowledging. You don't learn JavaScript by writing the perfect solution the first time. You write something that works, learn another concept, then look back and think "I could have done this better." That's not failure. That's progress.&lt;/p&gt;

&lt;p&gt;With AI making it increasingly easy to generate code, I think there's even more value in being able to look at what you wrote and think: &lt;strong&gt;"Yeah, I know why this works."&lt;/strong&gt; That's the level of JavaScript knowledge I'm trying to build, and why I'm going back through my old projects, not to rewrite everything for its own sake, but to understand why I wrote things the way I did, and what I'd do differently now.&lt;/p&gt;




&lt;h3&gt;
  
  
  Next up
&lt;/h3&gt;

&lt;p&gt;There's plenty more to revisit: closures, &lt;code&gt;this&lt;/code&gt;, higher-order functions, destructuring, spread &amp;amp; rest operators, promises &amp;amp; async/await, the event loop, DOM manipulation, fetch &amp;amp; APIs, modules, prototypes, optional chaining &amp;amp; nullish coalescing — and eventually, how all of this connects to React.&lt;/p&gt;

&lt;p&gt;Because apparently, &lt;strong&gt;"I know JavaScript"&lt;/strong&gt; and &lt;strong&gt;"I understand JavaScript"&lt;/strong&gt; are two completely different sentences. 😅 See you on the next one.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>programming</category>
      <category>learning</category>
    </item>
  </channel>
</rss>
