目標
- 在鍵盤上按下畫面中的英文 ASDFGHJKL 這幾個按鍵時,會播放相應的聲音,且頁面與字母相應的按鈕有外框變為黃色、字放大等特效樣式
- 放開按鍵時恢復初始狀態
step 1 : 監聽鍵盤按鈕事件
- 添加 keydown 的 listener
// 添加 keydown 事件的 listener,當使用者按下鍵盤的按鍵時,呼叫 playSound
window.addEventListener('keydown', playSound);
- function palySound
function playSound(e){
// 利用 data-key 以及 e.keyCode,取得對應的 audio 標籤及該按鍵的 class 名稱為 key 的元素
const audio = document.querySelector(`audio[data-key="${e.keyCode}"]`)
const key = document.querySelector(`.key[data-key="${e.keyCode}"]`)
// * 如果按的鍵是畫面中的英文字母以外的其他鍵,就不做任何反應,否則就播放音檔以及改變 style 樣式
// 檢查輸入的按鍵的 keyCode 是否有對應的 audio 標籤
// 如果沒有則 return
if(!audio) return
// 如果有的話,每次播放前,將播放時間設為 0
// 確保連續按的時候,可以連續播放出聲音
audio.currentTime = 0
// 播放元素的音效
audio.play()
// class 名稱為 key 的元素增加 playing 的 class
key.classList.add('playing')
}
step 2 : 監聽 transitionend 事件
- 添加 transitionend 的 listener
// 選取所有 class 名稱為 key 的元素
const keys = document.querySelectorAll('.key')
// 添加 transitionend listener,到所有 class 名為 key 的元素
// 在元素在 CSS transition 結束後觸發,transitionend,事件,呼叫 removeTransition
keys.forEach(key => key.addEventListener('transitionend', removeTransition))
- function removeTransition
function removeTransition(e){
// 判斷該觸發的元素傳入的 propretyName 是否為 transform,不是的話就 return
if(e.propertyName !== 'transform') return
// 是 transform 的話,則移除 playing 這個 class
this.classList.remove('playing')
}
HTML
1. 播放音效 <audio>
<audio data-key="65" src="audio 檔案的位置"></audio>
2. 用戶使用鍵盤輸入的標籤 <kbd>
Javascript
1. e.key
vs e.keyCode
e.key
: 偵測按下的字母(不包括 Shift、Ctrl 等非字母的按鍵)
e.keyCode
: 偵測按下的鍵盤鍵碼
2. JS 操作 DOM 元素增加/移除 / 切換 class
// 選取 class 名稱為 block 的元素
const block = document.querySelector('.block');
// 添加 class
block.classList.add('newClass');
// 移除 active
block.classList.remove('newClass');
// 偵測是否存在這個 class 名稱,存在則刪除 / 不存在則新增
block.classList.toggle('newClass');
// contains() 偵測是否存在這個 class 名稱, 返回 true/false
block.classList.contains('newClass');
3. querySelectorAll 會回傳節點的集合: NodeList
NodeList 是類陣列(不是陣列),有 length 和 forEach 的方法,但不能使用 map()。
參考資料:
- Make a JavaScript Drum Kit in Vanilla JS! #JavaScript30 1/30 @Wes Bos
- [Alex 宅幹嘛] 👨💻 深入淺出 Javascript30 快速導覽:Day 1:JavaScript Drum Kit @Alex 宅幹嘛
- JavaScript30 @guahsu
- 01 JavaScript Drum Kit 中文指南@soyaine
- [JS30] Day 01: JavaScript Drum Kit@PJCHENder
- JS30-Drum kit@Benben