01 – JavaScript Drum Kit
JavaScript 30 是由 WES BOS 制作的纯 JavaScript 教学,在该教程中一共会实现30个案例。本文用于记录在 DEMO 制作过程中遇到的问题以及思考。本文首发于个人博客,Enjoy Reading!
需求
键盘按下后,播放出对应按键的声音,并且在页面上的按钮显示一个简单的特效。
步骤
Step1: 监听键盘事件
为了让网页在全局下监听键盘,使用 window.addEventListener('keydown', function(){})
。
补充:keydown和keypress的区别
keydown
会被所有按键触发,但是keypress
只会被能生成字符值的按键触发。例如:方向键能触发keydown
,但是不能触发keypress
。keydown
的 event keycode 来说明是哪个按键触发了事件,而keypress
提供的 keycode 只会说明触发事件是哪个字符。例如:当键盘按下a
,keyboard
会报告65
,而keypress
会报告97
。值得注意的是,A
在任何的事件中都会报告为65
。
Step2: 创建播放函数
- 利用
keyCode
和data-key[]
判断按键对应的音频以及div元素。 - 使对应的div元素添加上
playing
的样式。 - 将
audio
的播放时间设为0,确保每次播放前音频从头开始。 - 播放音频。
补充1:audio其他常用的属性及方法
- 属性
- autoplay:布尔值属性;声明该属性,音频会尽快自动播放,不会等待整个音频文件下载完成。
- controls:如果声明了该属性,浏览器将提供一个包含声音,播放进度,播放暂停的控制面板,让用户可以控制音频的播放。
- loop:布尔属性;如果声明该属性,将循环播放音频。
- 方法
- pause:暂停播放。
补充2:classList
-
相比于之前用 js 操控 CSS,例如:
document.style.background="red";
document.style.fontSize="24";
相当于【元素的样式被改变了两次】,可能会导致回流和重绘,降低JavaScript性能。
-
必要的时候可以使用 list 列表的形式,例如:
document.getElementById("myDIV").classList.add("mystyle");
function playSound(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();
}
复制代码
.playing {
transform: scale(1.1);
border-color: #ffc600;
box-shadow: 0 0 1rem #ffc600;
}
复制代码
Step3: 监听transitione结束事件
- 获取所有包含
className=key
的元素。 - 当该元件触发特效并结束时触发函数。
const key = Array.from(document.querySelectorAll('.key'));
key.forEach(key => key.addEventListener('transitionend', function(){}))
复制代码
补充:ArrayForm
document.querySelectorAll()
获取到的元素是NodeList
,虽然NodeList
不是Array
,但仍然可以使用forEach
进行迭代,不过老旧的浏览器较为过时,没有实现NodeList.forEach()
。可以使用Array.prototype.forEach()
或Array.form()
来规避这一问题。
Step4: 创建removeTransition函数
- 判断传入事件的
peopertyName
是否为transform
,若否则退出。 - 若为
transform
,则移除playing
样式。
function removeTransition(e) {
if(e.propertyName !== 'transform') return;
e.target.classList.remove('playing');
}
复制代码
思考
在原案例中使用了CSS的排版语法:
.keys {
display: flex; /* 使用flex要现在元素内声明flex */
flex: 1; /* 简写,全称为flex: flex-grow|flex-shrink|flex-basis*/
min-height: 100vh; /* vh代表view height, 百分比呈现 */
align-items: center; /* 声明为flex后才有效的属性,垂直居中 */
justify-content: center;/* 声明为flex后才有效的属性,水平居中 */
}
复制代码
参阅
Document: keydown event – WebAPIs | MDN
Element.classList – Web APIs | MDN
flex – CSS: Cascading Style Sheets | MDN
在文章的最后,感谢 WES BOS
等国内外大佬将优秀作品开源,让学习的门槛变得更低,enjoy Coding!
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END