DOJO004

  • Dashool 創辦人
  • 喜歡調酒
  • Rails、Nextjs、TypeScript

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

可以在這個網站上按下鍵盤,就可以得到對應的 keycode 。https://www.toptal.com/developers/keycode

Q = 81
W = 87
E = 69 
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
    }
應該就可以看到流暢的動畫了!

版權所有 © 2023 DOJO004

Deployed on Zeabur