❤️ javascript30是一系列的視訊教程,旨在30天編寫30個前端小專案。 這些專案不需要使用其他lib,不需要編譯,不需要模板,迴歸最純真的JavaScript;
? ? ?
? 寫在前面: 我是從NodeJs轉向前端開發的,並且才半年時間左右,而且這半年更多的是進行React和Angular相關的開發,所以有很多前端基礎知識,比如HTML5和CSS3的新特性使用的並不好,通過這個系列的學習,可以更好的掌握基礎知識;
專案程式碼同步更新在男同交友網
專案簡介
Drum Kit專案是在相應使用者的鍵盤事件,改變對應的樣式和播放不同的audio,並且在完成後重置樣式;
知識點複習(附我學習的連結)
HTML
<audio>
標籤 使用 JavaScript 控制Audio物件<kdd>
標籤 用於表示使用者輸入的標籤 MDN-kdd
CSS
- flex佈局 一個完整的Flexbox指南, A Complete Guide to Flexbox
- background-size MDN-background-size
- transition MDN-transition
- transform MDN-transform
- letter-spacing MDN-letter-spacing
- rem 移動web適配利器-rem, 瞭解真實的『REM』手機螢幕適配
- vh: 1vh 等於1/100的視口高度。 7個你可能不認識的CSS單位, 談談CSS3的長度單位(vh、vw、rem)
JS
- Element.classList MDN-Element.classList
- document.querySelector(), document.querySelectorAll() [譯]你所不瞭解的querySelector
- transitionend event: transitionend 事件會在 CSS transition 結束後觸發 MDN-transitionend
NodeList.forEach()
: 英MDN-NodeList
程式碼實踐
編寫html:
這裡使用Emmet外掛快速編寫html程式碼,感興趣的朋友可以去了解一下Emmet;
監聽鍵盤事件:
function play(e) {
const audio = document.querySelector(`audio[data-key="${e.keyCode}"]`)
const key = document.querySelector(`.key[data-key="${e.keyCode}"]`)
if (!audio) return
audio.currentTime = 0; // 重置
audio.play();
key.classList.add('playing');
}
window.addEventListener('keydown', play);複製程式碼
監聽transitionend事件:
function removeTransition(e) {
console.log('ee:', e)
if (e.propertyName !== 'transform') return; // 如果不是transform完成過渡,則忽略
this.classList.remove('playing');
}
const keys = document.querySelectorAll('.key')
// 這裡按我以前的知識,總覺得它會錯
keys.forEach(key => key.addEventListener('transitionend', removeTransition));複製程式碼
.playing的樣式如下:
.playing {
transform: scale(1.2);
border-color: #ffc600;
box-shadow: 0 0 10px #ffc600;
}複製程式碼
遇到的坑
大家應該都知道一個類陣列(array like)的概念, 上面程式碼中const keys = document.querySelectorAll('.key')
得到的keys就是一個類陣列;
然後我印象中看過很多類陣列相關的材料,類陣列的定義如下:
- 擁有length屬性,其它屬性(索引)為非負整數(TO_NUMBER之後);
- 不具有如 push 、 forEach等陣列物件具有的方法
那麼為什麼keys是NodeList,明明是類陣列,為什麼有forEach
方法?這裡先展示倆個截圖:
原來NodeList雖然是類陣列物件,但是提供了forEach方法,但是中文的文件中卻沒有更新!
NodeList還提供了keys, values等方法!