JavaScript30 爲Wes Bos推出的一項爲期30天的挑戰,旨在幫助人們用純JavaScript來實現效果,初學者若想在JS方面快速精進,不妨一試。如今你看到的是該系列總結的第一篇,不知什麼時候能作完30題,就不在此信誓旦旦立flag了。javascript
個人項目地址是 js 1/30。css
利用JS實現模擬打鼓的效果,敲擊鍵盤字母(A-L),便可播放對應聲音,同時當前字母伴隨敲擊聲效出現動畫。 html
查看 demo。java
window.addEventListener('keydown', playaudio);
複製代碼
<div class="keys">
<div data-key="65" class="key">
<kbd>A</kbd>
<span class="sound">clap</span>
</div>
······
<!-- B-K部分代碼省略,請參閱代碼 -->
<div data-key="76" class="key">
<kbd>L</kbd>
<span class="sound">tink</span>
</div>
</div>
<audio data-key="65" src="sounds/clap.wav"></audio>
······
<!-- 部分代碼省略,請參閱代碼 -->
<audio data-key="76" src="sounds/tink.wav"></audio>
複製代碼
html {
font-size: 10px;
background: url(http://i.imgur.com/b9r5sEL.jpg) bottom center;
background-size: cover;
/* 把背景圖像擴展至足夠大,以使背景圖像徹底覆蓋背景區域。 */
}
body,html {
margin: 0;
padding: 0;
font-family: sans-serif;
}
.keys {
display: flex;
flex: 1;
min-height: 100vh;
/* 設置段落的最小高度,其中vh是可視區百分比高度單位,如1vh等於可視區高度的百分之一 */
align-items: center;
/* 彈性盒子元素在該行的側軸(縱軸)上居中放置。 */
justify-content: center;
/* 彈性盒子元素將向行中間位置對齊。該行的子元素將相互對齊並在行中居中對齊, 同時第一個元素與行的主起始位置的邊距等同與最後一個元素與行的主結束位置的邊距 */
}
.key {
border: .4rem solid black;
border-radius: .5rem;
/* 向 div 元素添加圓角邊框 */
margin: 1rem;
font-size: 1.5rem;
padding: 1rem .5rem;
transition: all .07s linear;
width: 10rem;
text-align: center;
color: white;
background: rgba(0,0,0,0.4);
text-shadow: 0 0 .5rem black;
}
.playing {
transform: scale(1.1);
border-color: #ffc600;
box-shadow: 0 0 1rem #ffc600;
}
/* 該樣式將在後文反覆說起 */
kbd {
display: block;
font-size: 4rem;
}
.sound {
font-size: 1.2rem;
text-transform: uppercase;
letter-spacing: .1rem;
color: #ffc600;
}
複製代碼
在初始代碼中,咱們能夠看到div.key和audio都傳入了一個data-key,能夠此爲突破口,只需找到與e.keyCode等值的標籤便可。git
const audio = document.querySelector(`audio[data-key="${e.keyCode}"]`);
const key = document.querySelector(`div[data-key="${e.keyCode}"]`);
複製代碼
經過此網站可快速查詢keyCode.github
設置audio播放時間爲0函數
audio.currentTime = 0;
複製代碼
添加transitionend事件,移除樣式。 transitionend 事件會在 CSS transition 結束後觸發。佈局
一樣添加鍵盤監聽事件,利用keyup移除效果。flex
window.addEventListener('keyup',removeT);
複製代碼
<script>
function removeT(e) {
if (e.propertyName !== 'transform') return;
e.target.classList.remove('playing');
}
function playaudio(e) {
const audio = document.querySelector(`audio[data-key="${e.keyCode}"]`);
const key = document.querySelector(`div[data-key="${e.keyCode}"]`);
if (!audio) return;
key.classList.add('playing');
audio.currentTime = 0;
audio.play();
}
const keys = document.querySelectorAll('.key');
keys.forEach(key => key.addEventListener('transitionend', removeT));
window.addEventListener('keydown', playaudio);
window.addEventListener('keyup', removeT);
複製代碼
var arr = [1, 2, 3];
for(var i = 0; i < arr.length; i++) {
console.log(arr[i]);
}
複製代碼
等同於,動畫
var arr = [1, 2, 3];
arr.forEach((val) => {
console.log(arr[i]);
})
複製代碼
也可用用reduce、map、filter這樣的函式代替,詳見該網站。
反引號``包裹字符串,常與${變量}連用。 普通字符串:
var a = 5;
var b = 10;
console.log("Fifteen is " + (a + b) + " and\nnot " + (2 * a + b) + ".");
// "Fifteen is 15 and
// not 20."
複製代碼
模板字符串:
var a = 5;
var b = 10;
console.log(`Fifteen is ${a + b} and\nnot ${2 * a + b}.`);
// "Fifteen is 15 and
// not 20."
複製代碼
另,在回顧總結中,發現liyuechun的博客,受益良多,記錄一筆。