Javascript 30 Day 01
JavaScript
這集的重點在於如何使用 data 這個 attributes。
開始囉
可以先 copy 基礎的程式碼。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <style> .key { border:4px solid black; border-radius: 5px; margin: 1rem; font-size: 1.5rem; padding: 1rem .5rem; transition: all 0.07s; width: 100px; text-align: center; } .playing{ transform: scale(1.1); border-color: #ffc600; box-shadow: 0 0 10px #ffc600; } </style> <body> <div class="keys"> <div data-key="" class="key">Q</div> <div data-key="" class="key">W</div> <div data-key="" class="key">E</div> <div data-key="" class="key">R</div> </div> </body> </html>
應該長得會像這樣。
找到按鍵對應的 keycode
Q = 81
W = 87
E = 69
R = 82
R = 82
keycode 的目的是為了要動態的取得按下的按鍵、對應的音效。
找到音效
什麼音效都可以,這邊提供免費的網站。
建議找 3~5 秒的音效。
之後在添加 audio 上去,綁上音效、data-key。
<audio data-key="81" src="analog-cymbal-90494.mp3"></audio> <audio data-key="87" src="boom-128320.mp3"></audio> <audio data-key="69" src="kick-183936.mp3"></audio> <audio data-key="82" src="solo-clap-90129.mp3"></audio> </body>
撰寫JS
監聽 “keydown” 事件
window.addEventListener('keydown', function(e){ console.log(e); })
可以在網頁的開發者工具看到,我們按下的按鍵包含了哪些資訊。
例如我按下了 Q,可以看到裡面有個 “keycode”,這是等等要利用的東西。
獲取 audio
接下來就可以利用 “datakey”、”keycode” 動態獲取要撥放的 audio。
window.addEventListener('keydown', function(e){ const audio = document.querySelector(`audio[data-key="${e.keyCode}"]`); console.log(audio); //查看是否獲得正確的 audio })
太好了,都正確!
播放 audio
再來就可以嘗試撥放 audio,並為了不讓程式出錯,添加一個保護機制,在找不到對應的 audio 之後,停止程式的執行。
window.addEventListener('keydown', function(e){ const audio = document.querySelector(`audio[data-key="${e.keyCode}"]`); if(!audio) return; //若找不到 audio 停止執行 audio.play(); })
無法重複撥放
再來你會發現到,即使重複按下 Q 也不會從頭開始撥放聲音,添加一行程式碼就好。
window.addEventListener('keydown', function(e){ const audio = document.querySelector(`audio[data-key="${e.keyCode}"]`); if(!audio) return; audio.currentTime = 0; // 讓音效從頭開始 audio.play(); })
加上文字特效
獲取對應的 “key” ,並加上 class。
window.addEventListener('keydown', function(e){ const audio = document.querySelector(`audio[data-key="${e.keyCode}"]`); const key = document.querySelector(`div[data-key="${e.keyCode}"]`); //取得對應的 key if(!audio) return; audio.currentTime = 0; audio.play(); key.classList.add('playing'); //加上 "playing" class })
應該就會看到效果了。
但是… 音樂播放完也沒有變回去,好像怪怪的?
添加回復動畫
其實非常簡單,只要將加上的 “playing” 清除掉就好。
獲取全部的 key,並為每一個 key 加上監聽事件。
function removeTransition(e){ console.log(e); } const keys = document.querySelectorAll('.key'); keys.forEach(key => key.addEventListener('transitionend', removeTransition));
removeTransition 是一個 function,我將他拉出來,方便維護、閱讀。
可以看到當 key 有變化時蹦出一堆訊息 :
我們只要其中一個 transition 的訊息就好,就可以將 “playing” 刪除。
function removeTransition(e){ if(e.propertyName !== 'transform') return; // 只要 transform this.classList.remove('playing'); // 刪除 "playing" class }
應該就可以看到流暢的動畫了!