2

I'm trying to target these elements:

<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>
<audio data-key="72" src="sounds/ride.wav"></audio>
<audio data-key="74" src="sounds/snare.wav"></audio>
<audio data-key="75" src="sounds/tom.wav"></audio>
<audio data-key="76" src="sounds/tink.wav"></audio>

So I'm trying to use this code to play them:

 window.addEventListener('keydown', function(e){
 const audio = document.querySelector('audio[data-key="${e.keyCode}"]');

 console.log(audio);
 if(!audio) return; // stop function
 audio.play();
 });

How ever, when pressing A, the data key returns Null. This is what the console says:

KeyboardEvent {isTrusted: true, key: "a", code: "KeyA", location: 0, 
ctrlKey: false, …}
index-START.html:65 Uncaught TypeError: Cannot read property 'play' of null
at index-START.html:65 

So I get I doesn't work, because it's Null. But I don't understand why its Null.

2 Answers2

4

Welcome to StackOverflow.

You need to use the string interpolation symbols ( ` ) around that string in order to do the ${...} substitution properly:

`audio[data-key="${e.keyCode}"]`

Otherwise the selector query is receiving the literal string which is trying to match elements with data-key equal to "${e.keyCode}". This is called a "template literal" and you can read more about the nuances here.

Alternatively, you could do this to avoid using a template literal and stick to standard quotes:

'audio[data-key="' + e.keyCode + '"]'
Graham
  • 7,431
  • 18
  • 59
  • 84
2

you made a small mistake in your query selector, your not using literal strings.

' should be `

const audio = document.querySelector(`audio[data-key="${e.keyCode}"]`);
Glenn Vandeuren
  • 356
  • 3
  • 14