Reputation: 135
I'm using JavaScript and CSS to create keys that flips and play a sound. On the front side there is an image then when the key is pressed, it plays a sound and flips to revels the back which displays a different img and flips back over after the key is released. The code works for that purpose, but I want the same functionality for when someone also clicks the key. Can I have both?
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();
}
const keys = Array.from(document.querySelectorAll('.key'));
keys.forEach(key => key.addEventListener('transitionend', removeTransition));
window.addEventListener('keydown', playSound);
Upvotes: 1
Views: 4145
Reputation: 22474
Yes, you can have both, you can do something like this:
function removeTransition(e) {
if (e.propertyName !== 'transform') return;
e.target.classList.remove('playing');
}
function playSound(e) {
let keyCode;
if (e.type === 'click') {
keyCode = e.currentTarget.dataset.key;
} else {
keyCode = e.keyCode;
}
const audio = document.querySelector(`audio[data-key="${keyCode}"]`);
const key = document.querySelector(`div[data-key="${keyCode}"]`);
if (!audio) return;
key.classList.add('playing');
audio.currentTime = 0;
audio.play();
}
const keys = Array.from(document.querySelectorAll('.key'));
keys.forEach(key => key.addEventListener('transitionend', removeTransition));
window.addEventListener('keydown', playSound);
keys.forEach(key => key.addEventListener('click', playSound))
I've used event.type to determine if the event is a click
or a keydown
and used element.dataset to retrieve the appropriate key in case of click
events (these events don't have the keyCode
property).
Also, in case of click
events, event.target
is actually the clicked key, you can use that instead of looking for the key in the DOM (the querySelector(`div[data-key="${keyCode}"]`)
call).
Upvotes: 3
Reputation: 11
Yes, as far as I am concerned, you can have as many event listeners per object as you want. Just use the relevant event listeners and attach them to the relevant HTML objects. Remember, in Javascript you need an event listener for each event. For example: (from https://gomakethings.com/listening-to-multiple-events-in-vanilla-js/)
This doesn't work:
document.addEventListener('click mouseover', function (event) {
// this doesn't work
}, false);
Instead, you'll have to do something like this:
var someFunction = function (event) {
// Do something...
};
// Add our event listeners
window.addEventListener('click', someFunction, false);
window.addEventListener('mouseover', someFunction, false);
Upvotes: 0