iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 1
1

成品連結:Drum Kit

事前準備

成品預期效果

當按下指定按鍵時,播放音效以及渲染畫面(新增/移除 class 'playing')

步驟

  • 監聽畫面按鍵
    • 渲染畫面:當按下指定按鍵時在 div.key 新增 playing 的 class
    • 播放音效
  • HTML 程式碼
  • CSS 程式碼

開始寫程式碼

首先我們先監聽瀏覽器按鍵事件,這裡我們選擇keydown事件。查詢各按鍵 keyCode 可以到這裡

這裡使用keypress也可以,但與keydown的差異是keypress的 keyCode 大小寫分別是不同數字,而且只對文字、符號按鍵有用(例如 Esc 或是 Ctrl 就無效)

window.addEventListener('keydown', function(e) {
    // 分別綁定key(畫面)與sound(音效檔案)
    const key = document.querySelector(`.keys > div[data-key="${e.keyCode}"]`);
    const sound = document.querySelector(`audio[data-key="${e.keyCode}"]`);
}

但由於我們只希望鍵盤 A ~ L 之間的按鍵有效果,為避免 key 與 sound 是null所以加一行 if statement 判斷,若是null則 return

// 確保在按到非指定按鍵時不會有反應
if (key === null) {return}

接著就可以開始渲染畫面和產生音效了!這裡分成畫面和聲音兩部分:

畫面渲染

  • 若 div.key 沒有 playing 這個 class 的話,我們新增它
  • 但我們只想要動畫延遲一小段時間,而不是永久新增 class playing,所以需要在 key 另綁定監聽事件,當 CSStransition結束時,移除 class playing。這裡我們使用 transitionend 這個事件來觸發動作,也就是當設定的transition: all .07s ease;結束時觸發
    • 由於 playing 更改的屬性有 border-colortransform以及box-shadow,所以我們只選擇一項當代表來當被監聽的元素(transform)

播放聲音

  • 播放聲音很簡單,只需要利用 audio 的 DOM 屬性 play()來播放即可
  • 若我們連擊按鍵不會有預期的重新播放效果,還是要等音效播放結束後才能重新開始,故當按下按鍵時,我們將音效的currentTime(當前時間)設定為 0 再播放已達到預期效果

以下是完成後的程式碼

window.addEventListener('keydown', function(e) {
    const key = document.querySelector(`.keys > div[data-key="${e.keyCode}"]`);
    const sound = document.querySelector(`audio[data-key="${e.keyCode}"]`);

    // 確保在按到非指定按鍵時不會有反應
    if (key === null) {return}

    // 渲染畫面,新增 class 'playing'
    key.classList.add('playing');
    // 當 transition 動畫結束後觸發事件
    key.addEventListener('transitionend', function(e) {
        // 更改的 css 很多,選一個當代表(transform)
        if(e.propertyName !== "transform") {return}
        // 移除 class 'playing'
        key.classList.remove('playing');
    });

    // 每次按鍵時重置開始時間至 0
    sound.currentTime = 0;
    sound.play();
});

大功告成!如此我們就完成了第一天的作品了!

心得

除了複習如何操作 DOM 元素,也學到了如何在 DOM 操做 html audio tag 以及 transitionend 的監聽事件。

參考連結


下一篇
JS30 Day 2 - JS & CSS Clock
系列文
一起挑戰 JavaScript 30 吧!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言