(1) JS實作系列 Drum-Kit

前言

本系列文章會實做一些JS的範例,從中熟練JS的觀念。

本文從第一個範例開始 Drum-Kit 範例程式碼

piano

keycode綁定

在這次挑戰中,要完成的是按下琴鍵後,播放指定音樂,和改變樣式。

所以第一步要做的是,選出指定的dom元素和音檔,

在 html 結構中,用 data-key分別對div 跟 audio 元素綁定對應按鍵的 keycode。

1
2
<div data-key="65" class="key">
<audio data-key="65" src="sounds/clap.wav"></audio>

事件監聽

要讓使用者能彈出聲音,要在window建立 keydown事件的監聽,當使用者按下鍵盤時,觸發對應函式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
window.addEventListener('keydown',playHandeler,false);
function playHandeler(e){
//播音樂
const audio = document.querySelector(`audio[data-key="${e.keyCode}"]`);
if(audio){
audio.currentTime = 0;//若要連續撥放 要設為0
audio.play();
}
//改樣式
const dom = document.querySelector(`div[data-key="${e.keyCode}"]`);
if(dom){
dom.classList.add('playing');
}
}

在函式中,用 ES6 的選取方法,用 audio[data-key=”${e.keyCode}”]直接選到 HTML 中的 [data-key]。
在利用 if 判斷式,判斷當使用者按到指定的按鍵時,也就是audio為true時,執行播放音檔,audio.play();
dom 為true時,執行classList.add(),彈奏時增加樣式。

動畫結束時,拿掉樣式

利用foreach,對每一個.key建立監聽,監聽事件為 transitionend 。這個事件是在css的 transition結束時觸發,也就是每一個drum kit撥放完時觸發。
要注意,若執行的transition屬性有很多種,如 transform、color、border-color,transitionend 會重複的觸發。
今天我們希望的是,在transform動畫結束時拿掉樣式,所以要加上判斷propertyName為 transform時,再執行 classList.remove拿掉樣式。

1
2
3
4
5
6
7
8
document.querySelectorAll('.key').forEach(function(item){
item.addEventListener('transitionend', transitionendHandler)
})
function transitionendHandler(e){
if(e.propertyName === 'transform'){
e.currentTarget.classList.remove('playing');
}
}

額外補充

若要在html 顯示 鍵盤按鍵 可以用 <kbd></kbd> 元素。