iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 1
0
自我挑戰組

JavaScript 30 挑戰日誌系列 第 1

Day 01:鍵盤鼓組

  • 分享至 

  • xImage
  •  

前言

進入前端這個變化多端的異世界也已一年半,
每每拿著新手 jQuery 雙手劍砍怪總覺得特別的笨重;
這時候就特別需要獲得 原生 JavaScript 的 效能Buff 加持!!

如果你也是打算從 jQuery 準備正式轉戰 原生JavaScript 的勇者,
歡迎一起組隊,經驗加倍! (笑

在這裡我寫的未必是最好的寫法,
若你也能有更好的寫法、想法或建議歡迎留言,
大家一起討論互相學習!

PS. 本次挑戰學習筆記是基於 Wes Bos 的 JavaScript30 挑戰課程:
https://javascript30.com/


Day 01:鍵盤鼓組

作品 Demo 連結: 傳送門

作品目標:按下鍵盤上對應的按鍵,發出對應的音效,並顯示特效。
難易度:★☆☆☆☆

HTML 於此僅列出 A鍵 及其對應的音效:

<!-- 按鍵 -->
<div data-key="65" class="key">
  <kbd>A</kbd>
  <span class="sound">clap</span>
</div>

<!-- 音效 -->
<audio data-key="65" src="sounds/clap.wav"></audio>

CSS 部分如果在 .key 上加入 .playing 則會有過度動畫產生:

.key {
 // ...略
 border: .4rem solid black;
 transition: all .07s ease;
}

.playing {
 transform: scale(1.1);
 border-color: #ffc600;
 box-shadow: 0 0 1rem #ffc600;
}

我們先來處理發出音效的功能,接著再來處理頁面動畫。

【第一步:選取將會使用到的目標】

var keys = document.querySelectorAll('.key');
var audios = document.querySelectorAll('audio');

首先我們先將所有的 .key 及 audio 選取出來
在 JavaScript 選取器中你可能曾經聽說過 getElementById / ClassName / Tag…
但是現在出現了比 getElementById 效能更高且更方便的 querySelector!
而且對於 jQuery 使用者也可以快速上手;
其實概念就是等於 jQuery 的 “$” 字號
選取器內容寫法跟 CSS, jQuery 方法一模一樣!
是不是很方便呢!?

querySelector 有分為兩種:
1. querySelector - 只會選取搜尋到的第一個對象
2. querySelectorAll - 以陣列形式儲存所有符合的對象
這次是使用後者,所以如果打算針對單個目標進行使用,請使用遍歷或過濾。

【第二步:綁定鍵盤下壓事件】

// 鍵盤事件綁定
window.addEventListener('keydown', function(event){
  findAudio(event);
});

此處的 addEventListener 近似於 jQuery 的 .on() 或者 .bind()
也就是綁定事件! 這次選擇綁定 keydown - 鍵盤下壓事件。

我們在此處透過 function 參數 event 來取得按鍵的詳細資訊。
因為在 HTML 當中,作者有給予鍵盤及音效相對應的 data-key,
所以我們在待會兒會透過 findAudio 函數取用 event 中的 .keyCode 部分。

【第三步:遍歷尋找對應音效檔並播放】

// 播放對應音效
function findAudio(keyDownEvent){
  audios.forEach(function(element){
    if(keyDownEvent.keyCode == element.dataset.key){
      element.currentTime = 0;  //目前播放時間設定為 0 
      element.play();  //播放音效
      findKey(keyDownEvent);  //執行動畫函數
    }
  });
}

在此處我們將之前已經選取的 audio 陣列來做遍歷。
透過 element.dataset.key 來取得當下元素的 data-key 內的數字,
如果數字與按鍵事件的 .keyCode 相同,
就將音效時間從 0 秒開始播放並且執行 findKey 函數後退出。

【第四步:螢幕過渡動畫製作】

// 對應按鍵 class 添加 .playing 改變畫面
function findKey(keyDownEvent){
  keys.forEach(function(element){
    if(keyDownEvent.keyCode == element.dataset.key){
      element.classList.add('playing');
    }
  });
}

這一步也是根據使用者按下的案件 keyCode
去尋找匹配的 .key 元素。
若條件符合則添加 .playing 執行動畫。

【第五步:綁定 Transition End 事件】

// 對應按鍵事件綁定
keys.forEach(function(element){
  element.addEventListener('transitionend', function(){
    element.classList.remove('playing');
  })
});

這裡綁定了一個不錯用的事件 "transitionend"
在過渡動畫完成之後立馬撤掉 .playing 類別回復成原樣,
這樣可以造成打鼓震動的錯覺


下一篇
Day 02:時鐘
系列文
JavaScript 30 挑戰日誌8
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言