오늘은 첫 게시물의 sequel을 다루려고 합니다! ✨
이전 게시물 및 Javascript Drum Kit
가 뭔지 모르신다면..!
이곳을 눌러서 확인 부탁드리겠습니다. 😛
이전 게시물에 Derek 구현 코드를 확인해보시면, 저는 switch-case
문으로 모든 keyCode
조건을 분기했었는데요,
function handleKeyDown(event){
switch(event.keyCode){
case 65:
currentKeyCode = "65";
playSound();
break;
case 83:
currentKeyCode = "83";
playSound();
break;
...
이런식으로 9개의 keyCode
를 토대로 일일히 case
를 만들었었습니다.
또한, 그렇게 분기되어서 각각은 currentKeyCode
값을 가지고 다음 playSound()
함수를 수행합니다.
function playSound(){
// add "playing" class
let targetKey = document.querySelector(`div[data-key = "${currentKeyCode}"]`);
targetKey.classList.add("playing");
// audio play
let audioKey = document.querySelector(`audio[data-key = "${currentKeyCode}"]`);
audioKey.play();
// remove playing class
setTimeout(() => targetKey.classList.remove("playing"), 500);
//targetKey.classList.remove("playing");
}
또한 playing
class를 지워주는 (잠깐 노란색으로 변하는 과정) 작업은 setTimeout
함수로 비동기적으로 0.5초 후에 실행하도록 설계했습니다.
이 모든 함수들은 사실
window.addEventListener("keydown", handleKeyDown);
이 eventListener
로 부터 시작이 되구요.
Wes Bos는 https://javascript30.com/ 를 이끌고 강의를 하는 분인데요,
이분의 강의 코드를 정리하고자 합니다.
아주.. 🐶고수이신것 같더라구요! 배울점이 많아서 기록하려고 합니다 😂
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);
코드의 흐름대로 내용을 제가 새로 접한 내용을 바탕으로 정리해보겠습니다!
playing
classfunction 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();
}
window.addEventListener('keydown', playSound);
조금은 제 코드와 비슷하지만, switch-case
를 쓰지 않고 바로 event.keyCode
로 접근하였습니다.
const audio = document.querySelector(`audio[data-key="${e.keyCode}"]`); const key = document.querySelector(`div[data-key="${e.keyCode}"]`);
백틱을 사용해서 event
로 넘어온 인자를 바로 keyCode
로 사용하면 굳이 제 코드처럼 switch-case
를 쓰지 않아도 되더라구요. 😅
중간에 audio.play()
전에 있는 audio.currenTime = 0;
를 잠깐 언급드리겠습니다!
저 구문이 없다면, 키보드 a, s, d, f, g, h, j, k, l
중 하나를 연속해서 빠르게 연타할때 약간 느리게 소리가 들리더라구요.
이는 sound.wav
파일의 재생 시간 때문에 빠르게 재생이 처음부터 안되고, 약간의 delay가 있는 것 처럼 재생되는 것이였습니다.
이를 해결하기 위해 매번 그 오디오 파일 (sound.wav
) 을 처음으로 rewind
해주는 구문이라고 보시면 될 것 같아요!
playing
class저는 추가된 playing
class를 지울때, 비동기적으로 setTimeout
함수를 통해 0.5초 후에 지우도록 했었습니다. 하지만 wes Bos
님의 코드를 보니 더 고급진 방법이 있더라구요..!
function removeTransition(e) {
if (e.propertyName !== 'transform') return;
e.target.classList.remove('playing');
}
const keys = Array.from(document.querySelectorAll('.key'));
keys.forEach(key => key.addEventListener('transitionend', removeTransition));
먼저 querySelectorAll
를 통해 class 값이 key
인 모든 class들을 찾아 list
형태로 keys
에 저장합니다.
그렇게 생성한 element
들에 대해서 하나하나 addEventListener
를 설정해주기보다는,
keys.forEach(key => key.addEventListener('transitionend', removeTransition));
이렇게 forEach
구문을 통해 하나하나에 대한 eventListener
를 설정해주었습니다.
저는 개인적으로 이 부분이 가장 효율적이다고 생각이 들어요!
사실 애초에 list
형태인 keys
에는 이런 코드는 에러를 발생시키는데요,
const keys = Array.from(document.querySelectorAll('.key')); keys.addEventListener("click", handleClick);
2번째 문장인 keys.addEventListener("click", handleClick);
는 list
형태인 keys
에 이벤트를 등록했기 때문에, 오류를 발생시킵니다.
이를 forEach
를 통해 간편하게 event
를 등록하는 게 정말 현명하다고 느껴졌습니다! 😆
또한, transitionend
라는 다소 생소한 이벤트를 사용했는데요,
그 정의는 이렇다고 합니다!
CSS를 전환이 완료되면 transitionend 이벤트가 발생한다.
즉 이번 Drum kit
프로젝트에서는 playing
class 가 추가되어 생기는 transition
이 끝나면,
removeTransition
함수를 실행시키는 형식입니다! removeTransition
함수는,
function removeTransition(e) {
if (e.propertyName !== 'transform') return;
e.target.classList.remove('playing');
}
이렇게 정의가 되어있는데요, 간단합니다! 먼저 발생한 이벤트에 transform
이 없다면 아무런 행동을 취하지 않고, 있다면 playing
class를 remove
하는 로직입니다.
이렇게 wes Bos
의 참고 코드도 리뷰해보았는데요, 간단한 구문이라도 매우 효율적으로 쓸 수 있음에 감탄하며.. 언제쯤 저렇게 되려나 고민도 하게 되는 강의였습니다..! 😥
감사합니다!🤗