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

這次的課程內容為,當我們鍵盤上特定的字母,網頁上的對應的字母便會發出爵士鼓的聲音,讓我們體驗到在網頁上打鼓~
觀看作者的範例中,我們可以分析出在按下鍵盤時發生了甚麼事情
按下鍵盤⇒對應的區塊發出聲音並且出現區塊邊特效⇒取消按壓後聲音及特效消失
將功能拆細的重點為
    <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個別對應了每個按鍵區塊以及聲音
playHandler
audio,賦值為綁定相對應的html的audio元素,‵audio[data-key="${e.keyCode}]‵,這個意思是說,假使我們按下A鍵 ,而A鍵的keyCode為65,則會尋找  元素if (audio):寫這個判斷式是為了判定是否有找到相對應的元素,意思是有找到元素的話則撥放聲音audio.play();如果不寫這段程式碼,而 audio 為空值(即找不到對應的 audio 元素),可能會導致後面程式報錯。keyStyle,用來綁定查找哪個div的data-key對應當前鍵盤按下的e.keyCode
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移除。
這樣的話能夠使該元素在過渡結束後恢復到原始狀態
JS30
[ Alex 宅幹嘛 ] 👨💻 深入淺出 Javascript30 快速導覽:Day 1:JavaScript Drum Kit
mdn web docs