I’m trying to learn JS by following The Odin Project, in which they recommended finishing a tutorial from this Github (JavaScript30), the first one involves triggering a highlight transition whenever a certain box is clicked or the corresponding key is pressed down.
I tried coding it myself first but found out that I’m not receiving the keydown
event ever but receiving the click event normally, after reviewing the solution I found that he’s assigning the event to window rather than the box itself.
why isn’t my box receiving the keydown event and why should I assign that to window ?
function togglePlaying(btn) {
console.log(btn);
btn.target.classList.toggle('playing');
};
document.querySelectorAll(".key").forEach((key) => {
console.log(key);
key.addEventListener('keydown', togglePlaying);
key.addEventListener('click', togglePlaying);
});
//window.addEventListener('keydown',togglePlaying);
html {
font-size: 10px;
background: url('./background.jpg') bottom center;
background-size: cover;
}
body,
html {
margin: 0;
padding: 0;
font-family: sans-serif;
}
.keys {
display: flex;
flex: 1;
min-height: 100vh;
align-items: center;
justify-content: center;
}
.key {
border: .4rem solid black;
border-radius: .5rem;
margin: 1rem;
font-size: 1.5rem;
padding: 1rem .5rem;
transition: all .07s ease;
width: 10rem;
text-align: center;
color: white;
background: rgba(0, 0, 0, 0.4);
text-shadow: 0 0 .5rem black;
}
.playing {
transform: scale(1.1);
border-color: #ffc600;
box-shadow: 0 0 1rem #ffc600;
}
kbd {
display: block;
font-size: 4rem;
}
.sound {
font-size: 1.2rem;
text-transform: uppercase;
letter-spacing: .1rem;
color: #ffc600;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JS Drum Kit</title>
<link rel="stylesheet" href="style.css">
<link rel="icon" href="https://fav.farm/🔥" />
</head>
<body>
<div class="keys">
<div class="key">
<kbd>A</kbd>
<span class="sound">clap</span>
</div>
<div class="key">
<kbd>S</kbd>
<span class="sound">hihat</span>
</div>
<div class="key">
<kbd>D</kbd>
<span class="sound">kick</span>
</div>
<div class="key">
<kbd>F</kbd>
<span class="sound">openhat</span>
</div>
<div class="key">
<kbd>G</kbd>
<span class="sound">boom</span>
</div>
<div class="key">
<kbd>H</kbd>
<span class="sound">ride</span>
</div>
<div class="key">
<kbd>J</kbd>
<span class="sound">snare</span>
</div>
<div class="key">
<kbd>K</kbd>
<span class="sound">tom</span>
</div>
<div class="key">
<kbd>L</kbd>
<span class="sound">tink</span>
</div>
</div>
2
Answers
Key Events start at the element which has the focus and bubble up the DOM from there.
The
div
elements aren’t (and don’t contain any)input
elements, elements with atabindex
or anything else what would allow them to hold the focus.What’s more, your design implies that it matters which key is pressed while looking at the page, not that any key can be pressed while the focus is on a particular element.
Binding the keydown listener to the
window
will capture any keydown event anywhere in the page. You can then use thekey
property of the event object to determine which key was pressed and use that information to search the DOM for the element you want to toggle the class on.I made a hashmap of the valid keys which are allowed to be pressed according to the structure of the divs. Then in window keydown listener, if the key pressed was one of those keys, activate its div.