挑戰 JS30 #1 - JavaScript Drum Kit

更新 發佈閱讀 7 分鐘

這系列文章會記錄 JS30 當次挑戰時使用到的語法和相關知識。

JS30 官方有提供所有製作網頁的資源,不需要任何事前準備,就能無痛開始撰寫 JS,寫完之後還有 JS30 作者提供的解答,不知道怎麼下手時可以參考、寫完之後也能了解更多解法,改善自己的寫法。

本次的挑戰是「JavaScript Drum Kit」,需要達成的目標是:

「使用者按下鍵盤特定按鍵,按鍵會發光、同時播放相對應的音效。」

根據上面這個目標,大略知道該挑戰牽涉到以下面向:

  • 事件綁定、鍵盤事件
  • 流程控制
  • 操作音效物件
  • DOM 操作 - 包括樣式修改、取得 DOM 元素等

嘗試拆解流程

流程圖

流程圖

這個挑戰有個小細節,就是每次按下鍵盤後,都必須將音效時間軸歸零,這樣在每次觸發時才會從頭開始播放音效。

知識點

音效物件

網頁中引入音效可以使用 <audio> 元素,原來 audio 本身有 API 可以進行操作,相當方便,以下就來了解看看吧。

<audio> 標籤

<audio​ src="filePath"></audio>

常見屬性

  • autoplay:自動播放音檔
  • controls:出現控制條
  • loop:循環播放

有看到一些文章會建議搭配 source 標籤,避免某些音檔格式瀏覽器不支援,而發生預期外的效果。如果 source 的第一個格式不支援,就會向下讀取其他項目,通常 mp3 會是最普及的格式,可以放在最後。

<audio autoplay>
<source src="xxx.ogg">
<source src="xxx.mp3">
你的瀏覽器不支援 HTML5 音訊格式。
</audio>

audio 相關 API

const audio = document.querySelector("audio")

//開始播放​
audio.play();

//暫停播放​
audio.pause();

//將音檔秒數歸零​
//audio 物件還有許多屬性,幾乎完全可以透過 JS 控制 audio
audio.currentTime = 0;

<kbd> 標籤

語意標籤,表示「鍵盤輸入按鍵」,預設樣式就會將字型變為等寬字(monospace)

附上此次實作結果

更好的寫法

參考作者的寫法,發現在取得 DOM 元素時就先篩選出符合的元素,但筆者在這邊都使用 forEach 迴圈做篩選。

下方比較兩者寫法,可以看出筆者寫法較為冗長,可讀性較低,且跑迴圈會佔較多效能。

  • 筆者的寫法
const keys = document.querySelectorAll(".key");

const filter = function (list, userKeyboard) {
let el;
list.forEach((item) => {
if (item.dataset.key === userKeyboard) {
el = item;
}
});
return el;
};

const playAudio = function (e) {
const audios = document.querySelectorAll("audio");
const userKeyboard = String(e.keyCode);
if (filter(keys, userKeyboard)) {
filter(keys, userKeyboard).classList.add("playing");
filter(audios, userKeyboard).currentTime = 0;
filter(audios, userKeyboard).play();
}
};
  • 作者的寫法
function playSound(e) {
const audio = document.querySelector(`audio[data-key="${e.keyCode}"]`);
const key = document.querySelector(`div[data-key="${e.keyCode}"]`);
console.log(e.keyCode);
if (!audio) return;

key.classList.add("playing");
audio.currentTime = 0;
audio.play();
}


增進使用體驗

製作完成後,發現有以下幾點可以做調整:

  1. 目前重複按下同一個鍵盤按鍵時,網頁按鈕樣式不會重複觸發,會一直亮著,雖然不影響使用,但希望有更細緻的體驗
  2. 如果完成第 1 點,會發現若鍵盤事件使用 keydown,當使用者按著按鍵不放時,事件會連續觸發,到某個程度時按鈕樣式就不再變動(簡言之「看起來」就像壞掉了XD);若鍵盤事件使用 keyup,雖然解決了事件重複觸發的問題,但筆者認為使用起來不符合預期效果,一般使用者應該會預期按下去的瞬間就發出音效,變成放開按鍵才發出音效似乎不夠即時

實作

一、重複點擊按鈕時,每次都會改變按鈕樣式

這部分是參考作者提供的解法,是使用transitionend 事件,監聽帶有 transition 屬性的元素,當 transitioned 結束時會觸發事件,有兩個情況下無法觸發該事件:

  • 在 transition 觸發以前元素就被設定 display: none
  • 有修改目標節點的 transition-property 屬性
function removeTransition(e) {
console.log(e.propertyName);
if (e.propertyName !== "transform") return;
e.target.classList.remove("playing");
}

作者是透過 propertyName 找到 transform 屬性,但似乎會導致重複觸發時按鈕樣式就不會再變動,不確定原因為何,目前想到的解決方式可往下看第二點。

二、在使用 keydown 的情況下,可以連續觸發樣式,且保持運作正常

解法1: 直接在 keyup 事件上綁定「清除按鈕樣式」的處理器,有點像買保險的感覺XD

let keys = document.querySelectorAll(".key");
const removeSound = function (e) {
keys.forEach((item) => {
item.classList.remove("playing");
});
};
window.addEventListener("keyup", removeSound);

解法2: transitionend 事件的 propertyName,找到除了 transform 以外的其他屬性,就能正常運作,這部分原因尚待釐清。

目前想到的解法是這樣,如果有更好的再補上。

題外話

發現下載後的檔案都有 favicon(瀏覽器頁籤會顯示的 icon),意外發現這個網站,可以自行替換掉後面的表情符號,蠻有趣的XD

今天就介紹到這裡,若有錯誤歡迎指正,也歡迎大家分享自己的看法。

參考資料

留言
avatar-img
傑米的沙龍
8會員
30內容數
正在一點一滴學習程式,相信知識量總有一天會匯聚成大海,目前專門研究前端中。
你可能也想看
Thumbnail
本文分析導演巴里・柯斯基(Barrie Kosky)如何運用極簡的舞臺配置,將布萊希特(Bertolt Brecht)的「疏離效果」轉化為視覺奇觀與黑色幽默,探討《三便士歌劇》在當代劇場中的新詮釋,並藉由舞臺、燈光、服裝、音樂等多方面,分析該作如何在保留批判核心的同時,觸及觀眾的觀看位置與人性幽微。
Thumbnail
本文分析導演巴里・柯斯基(Barrie Kosky)如何運用極簡的舞臺配置,將布萊希特(Bertolt Brecht)的「疏離效果」轉化為視覺奇觀與黑色幽默,探討《三便士歌劇》在當代劇場中的新詮釋,並藉由舞臺、燈光、服裝、音樂等多方面,分析該作如何在保留批判核心的同時,觸及觀眾的觀看位置與人性幽微。
Thumbnail
這是一場修復文化與重建精神的儀式,觀眾不需要完全看懂《遊林驚夢:巧遇Hagay》,但你能感受心與土地團聚的渴望,也不急著在此處釐清或定義什麼,但你的在場感受,就是一條線索,關於如何找著自己的路徑、自己的聲音。
Thumbnail
這是一場修復文化與重建精神的儀式,觀眾不需要完全看懂《遊林驚夢:巧遇Hagay》,但你能感受心與土地團聚的渴望,也不急著在此處釐清或定義什麼,但你的在場感受,就是一條線索,關於如何找著自己的路徑、自己的聲音。
Thumbnail
5 月將於臺北表演藝術中心映演的「2026 北藝嚴選」《海妲・蓋柏樂》,由臺灣劇團「晃晃跨幅町」製作,本文將以從舞台符號、聲音與表演調度切入,討論海妲・蓋柏樂在父權社會結構下的困境,並結合榮格心理學與馮.法蘭茲對「阿尼姆斯」與「永恆少年」原型的分析,理解女人何以走向精神性的操控、毀滅與死亡。
Thumbnail
5 月將於臺北表演藝術中心映演的「2026 北藝嚴選」《海妲・蓋柏樂》,由臺灣劇團「晃晃跨幅町」製作,本文將以從舞台符號、聲音與表演調度切入,討論海妲・蓋柏樂在父權社會結構下的困境,並結合榮格心理學與馮.法蘭茲對「阿尼姆斯」與「永恆少年」原型的分析,理解女人何以走向精神性的操控、毀滅與死亡。
Thumbnail
《轉轉生》(Re:INCARNATION)為奈及利亞編舞家庫德斯.奧尼奎庫與 Q 舞團創作的當代舞蹈作品,結合拉各斯街頭節奏、Afrobeat/Afrobeats、以及約魯巴宇宙觀的非線性時間,建構出關於輪迴的「誕生—死亡—重生」儀式結構。本文將從約魯巴哲學概念出發,解析其去殖民的身體政治。
Thumbnail
《轉轉生》(Re:INCARNATION)為奈及利亞編舞家庫德斯.奧尼奎庫與 Q 舞團創作的當代舞蹈作品,結合拉各斯街頭節奏、Afrobeat/Afrobeats、以及約魯巴宇宙觀的非線性時間,建構出關於輪迴的「誕生—死亡—重生」儀式結構。本文將從約魯巴哲學概念出發,解析其去殖民的身體政治。
Thumbnail
學習混音可以分為幾個步驟,即使你沒有經驗,也能逐步掌握這門技術
Thumbnail
學習混音可以分為幾個步驟,即使你沒有經驗,也能逐步掌握這門技術
Thumbnail
這篇文章是來響應跳鼠飛行日記的30天歌單挑戰 Day1-Day5,搜集了以金屬樂為主,我常聽的工作與創作用音樂。 其實我聽的金屬樂非常偏科,大量集中在主唱是女性的樂團上,不過為了顧及推薦的多樣性,還是會將我常聽且知名度高的樂團包含在名單內。 這個小系列會包括三十首歌,每篇十首,那就開始吧!
Thumbnail
這篇文章是來響應跳鼠飛行日記的30天歌單挑戰 Day1-Day5,搜集了以金屬樂為主,我常聽的工作與創作用音樂。 其實我聽的金屬樂非常偏科,大量集中在主唱是女性的樂團上,不過為了顧及推薦的多樣性,還是會將我常聽且知名度高的樂團包含在名單內。 這個小系列會包括三十首歌,每篇十首,那就開始吧!
Thumbnail
我是一個超級愛聽音樂的孩子。 音樂幾乎是我療癒、平靜心情的一個方式,以一個藝術創意型人來說,只要一個人的空間就會播放音樂,而音樂類型偏日韓流行類,在冥想、靜心、睡覺才會使用心靈音樂。 所以為什麼要試隨機模式? 我在最近深深感受到,隨機播放模式,也是種另類的「宇宙建議或者提醒」。
Thumbnail
我是一個超級愛聽音樂的孩子。 音樂幾乎是我療癒、平靜心情的一個方式,以一個藝術創意型人來說,只要一個人的空間就會播放音樂,而音樂類型偏日韓流行類,在冥想、靜心、睡覺才會使用心靈音樂。 所以為什麼要試隨機模式? 我在最近深深感受到,隨機播放模式,也是種另類的「宇宙建議或者提醒」。
Thumbnail
最近在練習吉他的彈奏,靈機一動,對著電視就練了起來。 原來我把電視轉到YouTube,找一些曾經聽過的懷舊老歌,先找到它的單音,再找它的調門和弦,最後就跟著一起彈奏起來,時不時還跟著唱。 這其實是我心目中最理想的「卡拉OK」,號稱「純人工手動的吉他卡拉OK」,因為這樣的音樂境界在我心目中才算OK
Thumbnail
最近在練習吉他的彈奏,靈機一動,對著電視就練了起來。 原來我把電視轉到YouTube,找一些曾經聽過的懷舊老歌,先找到它的單音,再找它的調門和弦,最後就跟著一起彈奏起來,時不時還跟著唱。 這其實是我心目中最理想的「卡拉OK」,號稱「純人工手動的吉他卡拉OK」,因為這樣的音樂境界在我心目中才算OK
Thumbnail
大約是在十多年以前,在公共電視台看了一個節目,裡面出現了一個音樂指揮家。在節目影片中有一段,是這名指揮家在翻閱一本厚厚的交響樂譜,隨後出現了他自己的旁白,大意是說當他看著樂譜的時候,他的腦海中會自動地出現各種樂器的聲音——它們依照樂譜裡的順序自動出現,開始交互起落、有強有弱,最後
Thumbnail
大約是在十多年以前,在公共電視台看了一個節目,裡面出現了一個音樂指揮家。在節目影片中有一段,是這名指揮家在翻閱一本厚厚的交響樂譜,隨後出現了他自己的旁白,大意是說當他看著樂譜的時候,他的腦海中會自動地出現各種樂器的聲音——它們依照樂譜裡的順序自動出現,開始交互起落、有強有弱,最後
Thumbnail
本文分享了作者初學樂器時的試煉,如何突破與學習樂器時遇到的困難。作者講述了從音樂基礎學習的重要性,並提到了一個Youtuber的節奏練習影片推薦。
Thumbnail
本文分享了作者初學樂器時的試煉,如何突破與學習樂器時遇到的困難。作者講述了從音樂基礎學習的重要性,並提到了一個Youtuber的節奏練習影片推薦。
Thumbnail
這系列文章會記錄 JS 30 當次挑戰時使用到的語法和相關知識。JS 30 官方有提供所有製作網頁的資源,不需要任何事前準備,就能無痛開始撰寫 JS,寫完之後還有 JS 30 作者提供的解答,不知道怎麼下手時可以參考、寫完之後也能了解更多解法,改善自己的寫法。
Thumbnail
這系列文章會記錄 JS 30 當次挑戰時使用到的語法和相關知識。JS 30 官方有提供所有製作網頁的資源,不需要任何事前準備,就能無痛開始撰寫 JS,寫完之後還有 JS 30 作者提供的解答,不知道怎麼下手時可以參考、寫完之後也能了解更多解法,改善自己的寫法。
Thumbnail
不會畫畫,不會作曲,只要出張嘴,就能當魔法師,還是自帶畫畫與音樂屬性的魔法師。
Thumbnail
不會畫畫,不會作曲,只要出張嘴,就能當魔法師,還是自帶畫畫與音樂屬性的魔法師。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News