iT邦幫忙

2024 iThome 鐵人賽

DAY 1
0
JavaScript

火箭通關JS30系列 第 1

JS30-01 - JavaScript Drum Kit

  • 分享至 

  • xImage
  •  

前情提要:

JS30,是由加拿大工程師Wes Bos所建立一系列課程,課程中我們可以學到很多JS的實際應用,對於我這種自學踏入前端的人來說,透過這些課題能夠對JS應用有更加深入的了解~
決定在這30天記錄學習筆記,在吸收知識的同時將學習到的知識點內化成自己的筆記

實做作品連結

課程目的:

image.png

這次的課程內容為,當我們鍵盤上特定的字母,網頁上的對應的字母便會發出爵士鼓的聲音,讓我們體驗到在網頁上打鼓~

本次功能實作重點:

觀看作者的範例中,我們可以分析出在按下鍵盤時發生了甚麼事情

按下鍵盤⇒對應的區塊發出聲音並且出現區塊邊特效⇒取消按壓後聲音及特效消失

將功能拆細的重點為

  • 按下鍵盤發出對應的聲音以及邊框特效
  • 假設長時間按壓音樂重複撥放
  • 取消按壓之後特效消失

按下鍵盤發出對應的聲音以及邊框特效

    <section class="keybox">
      <div class="key" data-key="65">
        <kbd class="kbd">A</kbd>
        <div class="sound">clap</div>
      </div>
      <div class="key" data-key="83">
        <kbd class="kbd">S</kbd>
        <div class="sound">hihat</div>
      </div>
      <div class="key" data-key="68">
        <kbd class="kbd">D</kbd>
        <div class="sound">kick</div>
      </div>
    
    </section>

    <audio src="/sounds/clap.wav" data-key="65"></audio>
    <audio src="/sounds/hihat.wav" data-key="83"></audio>
    <audio src="/sounds/kick.wav" data-key="68"></audio>
  

 function playHandler(e) {
    const audio = document.querySelector(`audio[data-key="${e.keyCode}"]`);
    if (audio) {
      audio.currentTime = 0; //為了將音頻的播放位置重置到開始位置
      audio.play();
    }
    //製作style
    const keyStyle = document.querySelector(`div[data-key="${e.keyCode}"]`);
    if (keyStyle) keyStyle.classList.add("playing"); //如果觸發keyStyle 則增加class playing
  }
  
  window.addEventListener("keydown", playHandler);
  

html我們可以看到作者設定了一個自訂屬性data-key個別對應了每個按鍵區塊以及聲音

  1. 我們先監聽整個視窗的”keydown”(按下鍵盤),並且命名一個函式為playHandler
  2. 命名變數為audio,賦值為綁定相對應的html的audio元素,‵audio[data-key="${e.keyCode}]‵,這個意思是說,假使我們按下A鍵 ,而A鍵的keyCode為65,則會尋找 元素
  3. if (audio):寫這個判斷式是為了判定是否有找到相對應的元素,意思是有找到元素的話則撥放聲音audio.play();如果不寫這段程式碼,而 audio 為空值(即找不到對應的 audio 元素),可能會導致後面程式報錯。
  4. 再來命名變數為keyStyle,用來綁定查找哪個div的data-key對應當前鍵盤按下的e.keyCode
  5. if (keyStyle): 如果有找到相應的keystyle則在此元素增加class playing標籤,增加此標籤使邊框出現特效

假設長時間按壓音樂重複撥放

   if (audio) {
      audio.currentTime = 0; //為了將音頻的播放位置重置到開始位置
      audio.play();
    }
    
    
     window.addEventListener("keydown", playHandler);

keydown的這個特性,長按一個鍵時,雖然我們只按下了一次,但實際上瀏覽器會將長按鍵視為一系列連續的 keydown 事件,而不是僅僅一個事件。也就是說,當長按鍵盤上的某個按鍵時,瀏覽器會不斷觸發 keydown 事件,類似於多次按下該鍵

於是我們可以利用這個特性去設定audio.currentTime = 0,因為長按使得一直觸發keydowm,在觸發的同時音檔會從頭撥放,並且在長壓的狀態下重複撥放

取消按壓之後特效消失

   function transitionHandler(e) {
    if (e.propertyName === "transform") {
      this.classList.remove("playing");
    }
  }
  
 document.querySelectorAll(".key").forEach((key) => {
    key.addEventListener("transitionend", transitionHandler);
  });
})();

key監聽的transitionend 事件用於監聽 CSS 過渡(transition)動畫的結束。意思是,它會在指定的 CSS 屬性完成過渡效果後觸發

當我們監聽到transitionend已完成時,便呼叫transitionHandler函式

設定一個判斷式e.propertyName === "transform”,意思是檢查觸發 transitionend 事件的屬性是否為 transform。如果是 transform,則進行this.classList.remove("playing");

this 指的是目前觸發事件的 DOM 元素

classList.remove("playing")意思是將當前key中的classlist中的playing移除。

這樣的話能夠使該元素在過渡結束後恢復到原始狀態

最後重點整理 :

  • 我們可以利用 data-* attribute來自定義自己想要的屬性
  • 學會用classList.add() classList.remove()在JS做出移除或增加class標籤的動作
  • addEventListener的"transitionend"跟"keydown"個別的用途

導讀文件以及學習資源

JS30
[ Alex 宅幹嘛 ] 👨‍💻 深入淺出 Javascript30 快速導覽:Day 1:JavaScript Drum Kit
mdn web docs


下一篇
JS30-02-JS and CSS Clock
系列文
火箭通關JS3030
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言