0

I am attempting to add a class of 'playing' to my division element so that when I 'keydown' on the specified key indicated by the 'kbd' element, the class of 'playing' with its properties will be applyied to the 'kbd' element.

None of this is happening. I keep getting this error : null is not an object (evaluating 'key.classList').

<style>
   .container {
      margin - top: 40 px;
      margin - left: 260 px;
   }
   .key {
      border: 1 px solid black;
      border - radius: 5 px;
      width: 100 px;
      padding: 1 rem.5 rem;
      margin: 1 rem;
      text - align: center;
      color: black;
      adds shadow to Text. text - shadow {
         hor position, vert position, color of the font - size: 1.5 rem;
         background: rgba(255, 255, 255, 0.4);
         - webkit - transition: all 0.07 s;
         display: inline - block;
      }
      kbd {
         display: block;
         font - size: 17 px;
         font - family: Heiti SC;
      }
      ;
      span {
         font - family: Heiti SC;
      }
      ;
      .keys {
         min - height: 100 vh;
         align - items: center;
         justify - content: center;
      }
      ;
      .playing {
         -webkit - transform: scale(1.1);
         border - color: #ffc600;
         box - shadow: 0 0 10 px# ffc600;
      }
      ;
</style>

Here is my html code

<div class = "container ">
   <!--    all kbb elemtns must be inline with each other with padding between them.       -->
   <div class = "keys">
      <!-- place border around keys -->
      <div data-key = "65" class = "key">
         <kbd class = "">a</kbd>
         <span class = "sound">Clap</span>
      </div>
      <div data-key = "83" class = "key">
         <kbd class = "">S</kbd>
         <span class = "sound">HiHat</span>
      </div>
      <div data-key = "68" class = "key">
         <kbd class = "">d</kbd>
         <span class = "sound">base</span>
      </div>
      <div data-key = "70" class = "key">
         <kbd class = "">f</kbd>
         <span class = "sound">OpenHat</span>
      </div>
      <div data-key = "71" class = "key">
         <kbd class = "">G</kbd>
         <span class = "sound">boom</span>
      </div>
      <!--         specifies an approach to embedding audio inside the web
         audio element :

          controls attribute : adds audio controls : play, pause, and volume

          <source> element allows specification of alternative audio files which the browser may choose from.

               -->
   </div>
</div>
<!-- Use data-* attribute to embed custom data  -->
<audio data-key = "65" src = "sounds/clap.wav"></audio>
<audio data-key = "83" src = "sounds/hihat.wav"></audio>
<audio data-key = "68" src = "sounds/kick.wav"></audio>
<audio data-key = "70" src = "sounds/openhat.wav"></audio>
<audio data-key = "71" src = "sounds/boom.wav"></audio>

Here is my JavaScript

window.addEventListener('keydown', function(e) {
    // Is there an audio element on the page that has a data-key of '65' ?

    // Use an attr selector
    // Use eS6 template strings contained is double quotes
    // This gets the correspoding audio element for that specific key
    const audio = document.querySelector(`audio[data-key = "${e.keyCode}"]`);
    if (!audio) return;

    /* The time between start and finish for the audio element is too long so use the currentTime property
    to make the audio rewind to the beginning instantly once the keydown event happens.*/
    audio.currentTime = 0; // rewind to the beginning.

    // Select a corresponding key
    const key = document.querySelector(`key[data-key = "${e.keyCode}"]`);
    // add a class of playing to the key class
    key.classList.add('playing');
    audio.play()
});
1
  • The error may be referring to key as null, rather than classList. Check if key is defined at that moment Commented Jul 25, 2017 at 0:01

2 Answers 2

1

About document.querySelector('key[data-key="${e.keyCode}"]'). key element is not here.

You mean document.querySelector('.key[data-key="${e.keyCode}"]')?

Sign up to request clarification or add additional context in comments.

4 Comments

Now it is showing me the 'undefined' primitive value
@WalthamWECAN Sorry, I typo singlequote to backquote, document.querySelector(`.key[data-key="${e.keyCode}"]`), div.key is playing class added?
@makamoto12 I already have the backticks ``. The aim is to add the 'playing' class to the div with the class of 'key'
@WalthamWECAN Please try: document.querySelector(`.key[data-key="${e.keyCode}"]`).classList.add('playing'); and check div.key element.
0

In the document.querySelector('key[data-key="${e.keyCode}"]') - key is specified as an element when you don't have an element with that name in your html.

It works with both div and .key - I just changed it to div.key to be more specific.

Just have a look at this code below, it fixes your issue. Check for if(key) to avoid any errors.

window.addEventListener('keydown', function(e) {
    // Is there an audio element on the page that has a data-key of '65' ?

    // Use an attr selector
    // Use eS6 template strings contained is double quotes
    // This gets the correspoding audio element for that specific key
    const audio = document.querySelector(`audio[data-key = "${e.keyCode}"]`);
    if (!audio) return;

    /* The time between start and finish for the audio element is too long so use the currentTime property
    to make the audio rewind to the beginning instantly once the keydown event happens.*/
    audio.currentTime = 0; // rewind to the beginning.
    // Select a corresponding key
    const key = document.querySelector(`div.key[data-key = "${e.keyCode}"]`);
    if(key){
      console.log('Key is: ' + e.keyCode);
      // add a class of playing to the key class
      key.classList.add('playing');
      audio.play()
    }
});
   .container {
      margin-top: 40px;
      margin-left: 260px;
   }
   .key {
      border: 1px solid black;
      border-radius: 5px;
      width: 100px;
      padding: 1rem .5rem;
      margin: 1rem;
      text-align: center;
      color: black;
      }
    kbd {
         display: block;
         font-size: 17 px;
         font-family: Heiti SC;
      }
      span {
         font-family: Heiti SC;
      }
      .keys {
         min-height: 100 vh;
         align-items: center;
         justify-content: center;
      }
      .playing {
         -webkit-transform: scale(1.1);
         border-color: #ffc600;
         box-shadow: 0 0 10px #ffc600;
      }
<div class = "container ">
   <!--    all kbb elemtns must be inline with each other with padding between them.       -->
   <div class = "keys">
      <!-- place border around keys -->
      <div data-key = "65" class = "key">
         <kbd class = "">a</kbd>
         <span class = "sound">Clap</span>
      </div>
      <div data-key = "83" class = "key">
         <kbd class = "">S</kbd>
         <span class = "sound">HiHat</span>
      </div>
      <div data-key = "68" class = "key">
         <kbd class = "">d</kbd>
         <span class = "sound">base</span>
      </div>
      <div data-key = "70" class = "key">
         <kbd class = "">f</kbd>
         <span class = "sound">OpenHat</span>
      </div>
      <div data-key = "71" class = "key">
         <kbd class = "">G</kbd>
         <span class = "sound">boom</span>
      </div>
      <!--         specifies an approach to embedding audio inside the web
         audio element :

          controls attribute : adds audio controls : play, pause, and volume

          <source> element allows specification of alternative audio files which the browser may choose from.

               -->
   </div>
</div>
<!-- Use data-* attribute to embed custom data  -->
<audio data-key = "65" src = "sounds/clap.wav"></audio>
<audio data-key = "83" src = "sounds/hihat.wav"></audio>
<audio data-key = "68" src = "sounds/kick.wav"></audio>
<audio data-key = "70" src = "sounds/openhat.wav"></audio>
<audio data-key = "71" src = "sounds/boom.wav"></audio>

3 Comments

I mean to access the division element with a class of 'key'.
I changes it to div and logged it to the console. It is now showing undefined.
@WalthamWECAN I modified the code above. This is running as you'd want it to. Hope it solves your issue.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.