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!