JS30官網
先到上方官網下載試題,今天就來試試看JS30第一天吧!主要是來講解作者是怎麼撰寫的!
這個題目主要做的是按下特定按鍵的時候會觸發聲音效果以及CSS並在結束動畫後刪除CSS樣式
我們先來看html
<div class="keys">
<div data-key="65" class="key">
<kbd>A</kbd>
<span class="sound">clap</span>
</div>
<div data-key="83" class="key">
<kbd>S</kbd>
<span class="sound">hihat</span>
</div>
<div data-key="68" class="key">
<kbd>D</kbd>
<span class="sound">kick</span>
</div>
<div data-key="70" class="key">
<kbd>F</kbd>
<span class="sound">openhat</span>
</div>
<div data-key="71" class="key">
<kbd>G</kbd>
<span class="sound">boom</span>
</div>
<div data-key="72" class="key">
<kbd>H</kbd>
<span class="sound">ride</span>
</div>
<div data-key="74" class="key">
<kbd>J</kbd>
<span class="sound">snare</span>
</div>
<div data-key="75" class="key">
<kbd>K</kbd>
<span class="sound">tom</span>
</div>
<div data-key="76" class="key">
<kbd>L</kbd>
<span class="sound">tink</span>
</div>
</div>
<audio data-key="65" src="sounds/clap.wav"></audio>
<audio data-key="83" src="sounds/hihat.wav"></audio>
<audio data-key="68" src="sounds/kick.wav"></audio>
<audio data-key="70" src="sounds/openhat.wav"></audio>
<audio data-key="71" src="sounds/boom.wav"></audio>
<audio data-key="72" src="sounds/ride.wav"></audio>
<audio data-key="74" src="sounds/snare.wav"></audio>
<audio data-key="75" src="sounds/tom.wav"></audio>
<audio data-key="76" src="sounds/tink.wav"></audio>
我們能發現div以及audio都有特定的key value
,需要靠這個來抓到特定元素
JS該怎麼做呢?
第一步我們先想一下我們除了按下按鈕會觸發音樂以及CSS樣式
第二步是要讓在動畫結束的時候刪掉CSS樣式!
也就是說在transitionend
的時候刪除樣式,keydown
的時候播放!
const keys = document.querySelectorAll('.key') //選到所有的按鈕
// 讓所有的key監聽keyup事件並刪除樣式
keys.forEach(key => key.addEventListener('transitionend', removeTransition));
// 在視窗上監聽keydown事件並播放
window.addEventListener('keydown', playSound);
我們先來做按下之後播放並新增playing的class吧!
我們剛剛綁定了視窗keydown事件,會觸發playSound function
那我們可以透過這個function選取到我們指定的按鍵!
我們使用 document.querySelector
選取到audio以及div,並透過data-key這個屬性來選取到我們按下的按鍵
Keycode就是每一個鍵盤按鈕的編號!透過這個api可以找尋到是不是我們所指定的按鍵跟音頻,如果沒有那就直接不做以下的程式!
function playSound(e) {
//透過e.keycode選擇音頻
const audio = document.querySelector(`audio[data-key="${e.keyCode}"]`);
//透過e.keycode選擇特定按鈕
const key = document.querySelector(`div[data-key="${e.keyCode}"]`);
// 沒有找到音頻就直接return不做!
if (!audio) return;
// 直接把選擇到的key新增playing這個css style
key.classList.add('playing');
// 每次按下就重新reset音頻的時間
audio.currentTime = 0;
// 播放音頻
audio.play();
}
我們現在就可以播放摟!但是會發現目前樣式還是無法刪除,就來解決吧!
function removeTransition(e) {
// console.log(e.propertyName)
if (e.propertyName !== 'transform') return;
e.target.classList.remove('playing');
}
剛剛有寫了如果在動畫結束後觸發removeTransition()
這邊使用propertyName
來判斷,如果不是動畫的就不做,如果是跟動畫有關的,那就把那一個按鈕的playing
CSS刪除!
這樣就能夠達成按下按鈕之後觸發音頻以及CSS樣式摟!
今天就講解到這邊,大家明天見!