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的博客,受益良多,记录一笔。