coding新手 第一次參加>"< 期許自己成功完成JS30!
當按下按鍵 A,S,D,F,G,H,K,L 按鍵時,播放對應的不同音效,頁面上對應的區塊會增添短暫樣式
keydown
data-*
e.keyCode
ClassList.add('')
forEach()
addEventListener
監聽每個 .keyArray.form()
data-key
屬性的值keydown
事件,取得按鍵 keyCode
querySelector
選取對應的 audio data-key
屬性的值並且添加 play()
querySelector
取得對應的 div data-key
並且添加 .playing樣式transitionened
事件,抓出改變的樣式區塊將其去除該樣式HTML5標籤<audio>
用於指定音源檔,增加controls屬性會有基本樣式
<audio data-key="65" src="sounds/clap.wav"></audio>
透過javascript控制
audio.currentTime = 0;
audio.play();
audio/video.play()
進行播放影片/音源audio/video.currentTime="seconds"
設置當前影片/音源的位置(以秒計)
範例中連續快速的音效用法:
添加play()播放音效時,需要等到音效結束,才能播放下一個音效,無法快速連續播放
可以在前面添加 currentTime = 0
設置音效當前位置為0秒,就可以狂按了
HTML5資料屬性data-*
其中的*
就是一個可以自定義的名稱,可添加自己需要的值
例如:data-name="yellow" or data-item="123"
// div上面
<div data-key="65" class="key">
// audio上面
<audio data-key="65" src="sounds/clap.wav"></audio>
透過javascript控制
之後會講到HTMLElement.dataset
範例裡面是用選取器,抓取HTML標籤的方式,並且加上ES6變數寫法
const audio = document.querySelector(`audio[data-key="${e.keyCode}"]`);
反回元件的class值(陣列),如果沒有就回傳空值
範例中使用add()以及remove()方法
key.classList.add('playing');
classList.add('aaa', 'bbb', 'ccc');
新增多個classNameclassList.remove('aaa', 'bbb', 'ccc');
移除多個className
如果已經存在/不存在的className則會被忽略。
跟for迴圈很像,單純執行每個陣列內的物件或值,不會額外回傳值
// 如果使用jQuery keys.addEventListener 是無法達成每個key都添加的
keys.forEach( key => key.addEventListener('transitionend', removeTransition));
範例中使用forEach為每個key增加監聽事件arr.forEach(function(item, index, array)
item物件,index索引,array全部陣列
在CSS完成transition後會觸發此事件
在這裡可以使用e.propertyName看到改變的屬性名稱
function removeTransition(e) {
if (e.propertyName !== 'transform') return;
e.target.classList.remove('playing');
}
在範例中發生 transition樣式屬性不只一個(box-shadow, transform, border-color)會出發3次,
所以增加判斷 if(e.propertyName !== 'transform') return;使每次按鍵事件觸發後只去除一次樣式
將物件或字串轉成陣列的方法
const keys = Array.from(document.querySelectorAll('.key'));
querySelectorAll 反為的是nodeList 而不是Array,
而nodeList 會少很多array能用的方法。
在這裡不使用也一樣能運作,只是可能在其他瀏覽器版本會有錯誤出現