這次,要紀錄自己在JS30 DAY的筆記,謝謝!
以下為原始檔
https://github.com/87JoJo/01---JavaScript-Drum-Kit
首先,我們所要的功能是按下特定字母,能夠發出聲音並聚焦。
首先我們需要一個鍵盤按下的事件,並放入一個playHandler的函數來產生對應聲音及樣式。
window.addEventListener('keydown', playHandler);
接著,在playHandler裡獲取對應的聲音、及DOM。
由於我們的HTML裡,設置的聲音及鍵盤元素如下,含有自定義屬性data-...
,可以利用自定義屬性來儲存所需要的資料,此處用來儲存鍵盤的keyCode,...為我們要定義的屬性名,且不可為大寫字母,也必須是字符串
。
<audio data-key="65" src="sounds/clap.wav"></audio>
<div data-key="65" class="key">
<!-- 專為鍵盤輸入的標籤(inline) -->
<kbd>A</kbd>
<span class="sound">clap</span>
</div>
由於我們所要獲取的元素含有屬性,因此利用模板字符串(``)方法來寫,${}裡面塞的就是我們所要的屬性
此處來講講兩種選擇器的差別。
querySelector為靜態選擇器
:當初獲取為多少,永遠就為多少,只要不再取一次,就不會變。getElementsByTagName為動態選擇器
:會隨著DOM增加或刪除做改變。
建議用靜態,可避免一些bug。
// 獲取對應聲音
const audio = document.querySelector(`audio[data-key="${e.keyCode}"]`);
// 獲取對應DOM
const dom = document.querySelector(`div[data-key="${e.keyCode}"]`);
而在播放聲音的部分,如果我們想要連續播放,記得在播放時將currentTime = 0;
// 播放聲音
// 如果想連續播放時間,記得每次播放之前將currentTime設成0
if (audio) {
audio.currentTime = 0;
audio.play();
}
而改變樣式的部分,利用classList增添playing的class以改變樣式。
if (dom) {
// 改變樣式
dom.classList.add('playing');
}
因為在css部分有對每個key都進行動畫效果,因此我們可利用在事件監聽動畫結束後,
並將class playing給移除,而playing所執行的樣式改變有transform、border-color、box-shadow等屬性。
/* 對全部key產生動畫效果 */
transition: all .07s ease;
在此之前我們需要獲取每個class為key的div,並且對每個key都去做動畫結束的事件監聽。
並且執行transitionHandler的函數來進行playing移入。
const everyDom = document.querySelectorAll('.key');
// 對每個key做迴圈處理
everyDom.forEach(function(k) {
// 對每個key都去做動畫結束的事件監聽
k.addEventListener('transitionend', transitionHandler);
});
我們按一下鍵盤,playing就會觸發很多處理(border顏色處理,shadow改變,transform)
獲取很多屬性如 "box-shadow","border-bottom-color","transform"...
// 但我們只需要propertyName為transform的屬性值
// 當我們動畫處理結束
if (e.propertyName === 'transform') {
// currentTarget當前觸發事件的目標
// 當我們完成動畫以後,就將對應樣式移除
e.currentTarget.classList.remove('playing');
}