Piano Project Aside

Off topic aside

Whenever we see a multitude of event listeners bells start going off. Perhaps a topic should be started relative to this project, but that addresses all the alarms.


  <section class="piano">
    <section id='c-key' class="key">
      <section class='keynote'>C</section>
    </section>
    <section id='c-sharp-key' class="black-key">
      <section class='black-keynote'>C#</section>
    </section>
    <section id='d-key' class="key">
      <section class='keynote'>D</section>
    </section>
    <section id='d-sharp-key' class="black-key">
      <section class='black-keynote'>D#</section>
    </section>
    <section id='e-key' class="key">
      <section class='keynote'>E</section>
    </section>
    <section id='f-key' class="key">
      <section class='keynote'>F</section>
    </section>
    <section id='f-sharp-key' class="black-key">
      <section class='black-keynote'>F#</section>
    </section>
    <section id='g-key' class="key">
      <section class='keynote'>G</section>
    </section>
    <section id='g-sharp-key' class="black-key">
      <section class='black-keynote'>G#</section>
    </section>
    <section id='a-key' class="key">
      <section class='keynote'>A</section>
    </section>
    <section id='a-sharp-key' class="black-key">
      <section class='black-keynote'>A#</section>
    </section>
    <section id='b-key' class="key">
      <section class='keynote'>B</section>
    </section>
    <section id='high-c-key' class="key">
      <div class='keynote'>C</div>
    </section>
  </section>

The above is a perfect example of superfluousness.

How many elements in the page have a class, piano? There is but the one. The hint here is to use an element type that appears nowhere else. It is the parent element. Caching this gives us an iterable collection.

Say we call the parent, <article> and cache that…

const piano = document.querySelector('article')

That is the collection our listener should be attached to.


Let’s say that all the components of our article are anchors with no href. That would make them essentially <span/> elements, no? Then we make their children <span/> elements for real. Both would be given display: block properties.

article a {
    display: inline-block;
}
article span {
    display: block;
}
  <article>
    <a id='c-key' class="key">
      <span class='keynote'>C</span>
    </a>
    <a id='c-sharp-key' class="black-key">
      <span class='black-keynote'>C#</span>
    </a>
    <a id='d-key' class="key">
      <span class='keynote'>D</span>
    </a>
    <a id='d-sharp-key' class="black-key">
      <span class='black-keynote'>D#</span>
    </a>
    <a id='e-key' class="key">
      <span class='keynote'>E</span>
    </a>
    <a id='f-key' class="key">
      <span class='keynote'>F</span>
    </a>
    <a id='f-sharp-key' class="black-key">
      <span class='black-keynote'>F#</span>
    </a>
    <a id='g-key' class="key">
      <span class='keynote'>G</span>
    </a>
    <a id='g-sharp-key' class="black-key">
      <span class='black-keynote'>G#</span>
    </a>
    <a id='a-key' class="key">
      <span class='keynote'>A</span>
    </a>
    <a id='a-sharp-key' class="black-key">
      <span class='black-keynote'>A#</span>
    </a>
    <a id='b-key' class="key">
      <span class='keynote'>B</span>
    </a>
    <a id='high-c-key' class="key">
      <span class='keynote'>C</span>
    </a>
  </article>

Do we need the class, key? No. It is a member of this collection, that is all we need to know.

why a?

The objects are clickable, that’s why. The mouse can interact with a click, that makes them a link, of sorts.

Going forward…

1 Like

Do we need an id attribute on any of the keys? No.They can be found because they are the n-th element in the collection and with proper delegation the target element of an event. That is enough to identify it in real time.


Just so we’re clear,

piano.onclick = playKey
2 Likes

I know it can be done, in theory; now it is up to you smart asses to prove me wrong. Better still, prove me right. Go to it…!

2 Likes