Refatoração dos eventos de clique
Sua lógica foi: adicionar um evento de click no próprio body da página e verificar se o target era um dos elementos que deveria tocar o áudio quando fosse clicado. Mas para deixar dinâmico, iremos na verdade adicionar um evento de clique próprio para cada uma das divs .key, ok? Assim poderemos aproveitar algumas informações da própria div. Ah, e não vamos mais precisar do código a partir da linha 28 do seu arquivo script.js do github.
Em seguida, vamos nos aproveitar do seu código que já seleciona as keys:
const keys = Array.from(document.querySelectorAll('.key'));
E podemos adicionar o seguinte código:
keys.forEach(function (key, keyPosition) {
key.addEventListener('click', function () {
console.log('Clicou na div key!');
// Falta código para tocar o áudio
});
});
Você já pode testar e ver que imprimimos "Clicou na div key!" no console sempre que clicamos em qualquer das divs. Além disso, não precisamos nos preocupar em também adicionar o evento de clique para os filhos das divs .key, graças ao Event bubbling do javascript, que faz com que o evento seja acionado tanto pelo próprio elemento quanto pelos seus filhos.
Note também que eu passei dois parâmetros para a função anônima: key e keyPosition. Por padrão, podemos passar dois parâmetros na função que usamos dentro do forEach, sendo que nesse caso key representa o elemento atual que estamos iterando e keyPosition é a posição do elemento atual também.
Por fim, agora vamos nos aproveitar dessa sua linha de código:
const audios = Array.from(document.querySelectorAll('audio'))
E perceba que os elementos desse array audios têm as mesmas posições correspondentes que os elementos do array keys. Vamos tirar vantagem disso e retornar para o código do forEach, substituindo pelo seguinte:
keys.forEach(function (key, keyPosition) {
key.addEventListener('click', function () {
console.log('Clicou na div key!');
key.classList.add('playing');
audios[keyPosition].currentTime = 0
audios[keyPosition].play()
});
});
Ou seja, se clicarmos na primeira div .key, que tem posição 0, também tocaremos o áudio da posição 0, e assim por diante! Conseguimos reduzir 50 linhas de código com apenas esse trecho! Em caso de dúvida, aqui está o código JS completo:
function removeTransition(event) {
if (event.propertyName !== 'transform') return;
event.target.classList.remove('playing');
}
function playSound(event) {
const audio = document.querySelector(`audio[data-key="${event.code}"]`);
const key = document.querySelector(`div[data-key="${event.code}"]`);
if (!audio) return;
key.classList.add('playing');
audio.currentTime = 0;
audio.play();
/*setTimeout(function(){
key.classList.remove("playing")
}, 200)*/
}
const audios = Array.from(document.querySelectorAll('audio'))
const keys = Array.from(document.querySelectorAll('.key'));
keys.forEach(key => key.addEventListener('transitionend', removeTransition));
window.addEventListener('keydown', playSound);
keys.forEach(function (key, keyPosition) {
key.addEventListener('click', function () {
console.log('Clicou na div key!');
key.classList.add('playing');
audios[keyPosition].currentTime = 0
audios[keyPosition].play()
});
});
É isso, espero ter te ajudado! Você está indo muito bem e até aprendi novas informações com o seu código. Continue assim e bons estudos!