I recently have been learning more JavaScript as I am going to be using it a lot for an upcoming internship. The company recommended many different resources for me to look at, but a friend of mine also suggested this website:
I decided to give it a try and started yesterday on the first project which was a JavaScript drumkit.
So the overall project wasn't hard, but I noticed a little bug that was happening. So the project attaches a 'keydown' event listener to several different HTML elements that trigger when either ASDFGHJKJL are pressed. In addition to playing a sound, the listener also attaches a class to the element that adds a little effect to the key being pressed.
To remove the class, we attached a transitionend listener to the elements. So when the CSS property finishes the transition after the key is pressed, the class is then removed and the graphic goes back to normal in the browser.
Now if you press the keys slowly, it works perfectly fine. But I noticed that if you were to hold a key down for a second or two, it appears as though the class that gets added is never removed and the graphic is permanent. I then checked the console and noticed that the transitionend event never fires once it gets stuck like that.
Here is the code from the finished file.
function removeTransition(e)
{
if (e.propertyName !== 'transform')
return;
e.target.classList.remove('playing');
}
function playSound(e)
{
const audio = document.querySelector(`audio[data-key="${e.keyCode}"]`);
const key = document.querySelector(`div[data-key="${e.keyCode}"]`);
if (!audio)
return;
key.classList.add('playing');
audio.currentTime = 0;
audio.play();
}
And this is how we attached the transitionend listener, not sure if this would have anything to do with it
const keys = Array.from(document.querySelectorAll('.key'));
keys.forEach(key => key.addEventListener('transitionend', removeTransition));
So we put in the if loop in the removeTransition function so that it doesn't remove the class for each property that is transitioning, but I noticed that when you remove the if loop, the page works perfectly.
So I am not entirely sure what is going on with the transitionend event, and why it just stops firing entirely once it gets stuck like that. And also, why it works when the if loop is removed. Maybe it has more chances to remove the class when it loops through all of the properties? No clue. Was wondering if anyone here might know what is going on.
EDIT:
I altered the playSound function a little bit to try and get to the bottom of this.
function playSound(e)
{
const audio = document.querySelector(`audio[data-key="${e.keyCode}"]`);
const key = document.querySelector(`.key[data-key="${e.keyCode}"]`);
if(!audio)
{
return;
}
if(key.classList.contains("playing"))
{
console.log("True");
key.classList.remove("playing");
}
audio.currentTime = 0;
audio.play();
console.log("adding");
key.classList.add("playing");
}
So I added an if statement that checks if the element already contains the "playing" class once it gets stuck. I also added a classList.remove call to try and get rid of it in that same branch. What I found was once it gets stuck, and I press the key again, it branches off into that if statement and prints the console message, but STILL will not remove the "playing" class.