YiDaoJ's Blog

JavaScript30 - 01 JavaScript Drum Kit

该练习来自Wes BosJavascript30的项目,旨在三十天内每天进行一个JavaScript练习。该项目的完整文档和答案地址:JavaScript30-Github
本文是自己在练习过程中的思路小节。欢迎交流。

在线演示


思路

  • 监听keydown事件,在该事件被触发时播放音效,相应的call-back function被调用:

    window.addEventListener('keydown', fucntion)

  • 播放音频时,相应的页面HTML按钮元素显示动画效果:

    element.classList.add('animation')

  • 动画效果完毕后,该元素恢复到起始状态:

    element.clasList.remove('animation')

具体实现

1. 监听keydown事件,playAudio作为call-back function被调用,在该事件被触发时播放音效。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function playAudio(e) {
// 事件e(此处为keydown)中包含属性keyCode,
// 因此利用HTML5的data特性,将按键和HTML元素进行关联,
// 以此来获取要播放的音频文件(元素)和添加动画效果的元素。
const audio = document.querySelector(`audio[data-key="${e.keyCode}"]`);
const key = document.querySelector(`.key[data-key="${e.keyCode}"]`);
// 如果该keyCode有相关联的音频元素,那么继续执行后面的代码;否则到此结束。
if(!audio) return; // stop the function from running all together
// otherwise error message: Uncaught TypeError: Cannot set property 'currentTime' of null
// 将音频文件时间重置为0,避免因音频未播放完毕导致后来多次按下同一按键无播放效果
audio.currentTime = 0; // set(rewind) the audio to start
// 播放音频
audio.play();
// 给相应的div元素添加动画效果
key.classList.add('playing');
}
// 监听keydown事件
window.addEventListener('keydown', playAudio);

2. 页面按钮的动画效果与恢复

在playAudio方法中给页面中的按钮元素添加了动画效果,改变了按钮元素的大小、边框、阴影式样。

那么如何去掉按钮元素的动画效果呢?

监听按钮元素的transitionend事件,从下图可以到每一次按下音频按键,该按键发生了transition后的TransitionEventTransitionEvenet有很多propertyName,这些propertyName依赖于通过css对该元素进行了哪些样式的改变。 ​

可以从中选择一个transformpropertyNameEvent进行操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
function removeTransition(e) {
// console.log(e);
// 如果该transitioned事件含有名为transform的属性,那么继续进行操作;否则就此退出。
if(e.propertyName !== 'transform') return;
// this为触发了该事件的当前元素,去除之前添加的playing样式。
this.classList.remove('playing');
}
// 获取所有含"key"-class的元素
const keys = document.querySelectorAll(".key");
// 利用forEach方法进行遍历,为每一个元素添加transitionend事件监听。
keys.forEach(key => key.addEventListener('transitionend', removeTransition));


其他

Template literals / 模板字面量

Template literals 是允许嵌入表达式的字符串字面量。

语法:`字符串${表达式}字符串`

示例:

1
2
3
4
5
6
var a = 5;
var b = 10;
// 普通字符串嵌入表达式
console.log("Fifteen is " + (a + b) + " and\nnot " + (2 * a + b) + ".");
// 利用template literals
console.log(`Fifteen is ${a + b} and\nnot ${2 * a + b}.`);

具体可参看MDN文档