前言
好久没有写好玩的小demo了,今天来实现一个敲击键盘的打击乐小demo,具体效果如下。
代码实现原理其实很简单,给每个键盘绑定一个audio,当用户敲击键盘时,我们能够拿到一个keyCode,通过给键盘设置data-key,再写一个简单函数实现音乐播放。
下面我们直接上代码,并讲解其中一些主要的注意点。
HTML代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>HTML5商业化开发细节</title>
<link rel="stylesheet" href="./common.css">
<script src="./index.js"></script>
</head>
<body>
<div class="keys">
<div class="keys1">
<div class="key" data-key="81">
<div>Q</div>
<span class="sound">clap</span>
</div>
<div class="key" data-key="87">
<div>W</div>
<span class="sound">hihat</span>
</div>
<div class="key" data-key="69">
<div>E</div>
<span class="sound">kick</span>
</div>
<div class="key" data-key="82">
<div>R</div>
<span class="sound">openhat</span>
</div>
<div class="key" data-key="84">
<div>T</div>
<span class="sound">openhat</span>
</div>
<div class="key" data-key="89">
<div>Y</div>
<span class="sound">ride</span>
</div>
<div class="key" data-key="85">
<div>U</div>
<span class="sound">snare</span>
</div>
<div class="key" data-key="73">
<div>I</div>
<span class="sound">tom</span>
</div>
<div class="key" data-key="79">
<div>O</div>
<span class="sound">tink</span>
</div>
<div class="key" data-key="80">
<div>P</div>
<span class="sound">tink</span>
</div>
</div>
<div class="keys2">
<div class="key" data-key="65">
<div>A</div>
<span class="sound">clap</span>
</div>
<div class="key" data-key="83">
<div>S</div>
<span class="sound">hihat</span>
</div>
<div class="key" data-key="68">
<div>D</div>
<span class="sound">kick</span>
</div>
<div class="key" data-key="70">
<div>F</div>
<span class="sound">openhat</span>
</div>
<div class="key" data-key="71">
<div>G</div>
<span class="sound">openhat</span>
</div>
<div class="key" data-key="72">
<div>H</div>
<span class="sound">ride</span>
</div>
<div class="key" data-key="74">
<div>J</div>
<span class="sound">snare</span>
</div>
<div class="key" data-key="75">
<div>K</div>
<span class="sound">tom</span>
</div>
<div class="key" data-key="76">
<div>L</div>
<span class="sound">tink</span>
</div>
</div>
<div class="keys3">
<div class="key" data-key="90">
<div>Z</div>
<span class="sound">clap</span>
</div>
<div class="key" data-key="88">
<div>X</div>
<span class="sound">hihat</span>
</div>
<div class="key" data-key="67">
<div>C</div>
<span class="sound">kick</span>
</div>
<div class="key" data-key="86">
<div>V</div>
<span class="sound">openhat</span>
</div>
<div class="key" data-key="66">
<div>B</div>
<span class="sound">openhat</span>
</div>
<div class="key" data-key="78">
<div>N</div>
<span class="sound">ride</span>
</div>
<div class="key" data-key="77">
<div>M</div>
<span class="sound">snare</span>
</div>
</div>
</div>
<!-- 音频资源 -->
<audio src="./sounds/clap.wav" data-key="65"></audio>
<audio src="./sounds/hihat.wav" data-key="83"></audio>
<audio src="./sounds/kick.wav" data-key="68"></audio>
<audio src="./sounds/openhat.wav" data-key="70"></audio>
<audio src="./sounds/boom.wav" data-key="71"></audio>
<audio src="./sounds/ride.wav" data-key="72"></audio>
<audio src="./sounds/snare.wav" data-key="74"></audio>
<audio src="./sounds/tom.wav" data-key="75"></audio>
<audio src="./sounds/tink.wav" data-key="76"></audio>
<audio src="./sounds/1.wav" data-key="81"></audio>
<audio src="./sounds/2.wav" data-key="87"></audio>
<audio src="./sounds/3.wav" data-key="69"></audio>
<audio src="./sounds/4.wav" data-key="82"></audio>
<audio src="./sounds/5.wav" data-key="84"></audio>
<audio src="./sounds/6.wav" data-key="89"></audio>
<audio src="./sounds/7.wav" data-key="85"></audio>
<audio src="./sounds/8.wav" data-key="73"></audio>
<audio src="./sounds/9.mp3" data-key="79"></audio>
<audio src="./sounds/10.mp3" data-key="80"></audio>
<audio src="./sounds/clap.wav" data-key="90"></audio>
<audio src="./sounds/hihat.wav" data-key="88"></audio>
<audio src="./sounds/kick.wav" data-key="67"></audio>
<audio src="./sounds/openhat.wav" data-key="86"></audio>
<audio src="./sounds/boom.wav" data-key="66"></audio>
<audio src="./sounds/ride.wav" data-key="78"></audio>
<audio src="./sounds/snare.wav" data-key="77"></audio>
</body>
</html>
排版没什么好讲的,这里主要是介绍一下HTML5中自定义数据属性data-key。
data-key
data-key
是HTML5中的自定义数据(data-*)属性之一,用于在HTML标签上存储自定义数据。在 HTML 中,你可以通过在标签上添加data-
前缀来定义自定义数据属性。在上述应用中,我们使用每个按键的data-key
属性存储了对应的键码(keyCode)。你可以使用任意合法的属性名来代替*
部分。例如,data-color
、data-user-id
等。这个属性是我们实现键盘交互非常重要的元素。
CSS部分
/* 业务样式 */
html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,
acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,
strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,
table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,
header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,
video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,
section {
display: block;
}
body {
line-height: 1;
}
ol,ul {
list-style: none;
}
blockquote,q {
quotes: none;
}
blockquote:before,
blockquote:after,
q:before,
q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
html {
height: 100vh;
font-size: 10px;
background: url('./2.jpg') bottom center;
background-size: cover;
}
body,html {
font-family: sans-serif;
}
.keys {
/* 水平垂直居中 */
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
flex-wrap: wrap;
min-height: 100vh;
}
.keys1,
.keys2,
.keys3 {
display: flex;
}
.key {
border: .4rem solid #000;
border-radius: .5rem;
margin: 1rem;
font-size: 1.5rem;
padding: 1rem .5rem;
transition: all .07s ease;
width: 10rem;
text-align: center;
color: white;
text-shadow: 0 0 .5rem black;
}
.key:hover {
border-color: red;
}
.playing {
transform: scale(1.1);
border-color: #ffc600;
box-shadow: 0 0 1rem #ffc600;
}
.key div {
font-size: 4rem;
}
.sound {
font-size: 1.2rem;
text-transform: uppercase;
letter-spacing: normal;
color: #ffc600;
}
对于还没去过企业上班或者实习的掘友(比如博主本人^-^)来说,可能不明白为什么最开始为什么要把基本上所有标签全列出来,在大学的学习中,或者自己自学在网上上网课,大部分老师通常都是像下面这样设置。
*{
padding: 0;
margin: 0;
}
的确很省事,对吧,不过一般企业开发却都不会使用上面这种简单的,它带来的性能是不好的。我去查询了几家大厂的网页源码,无一例外,他们都是按第一种来设置的。
豆瓣
腾讯
不过平时书写代码不太关心性能问题,我们按第二种设置也省事,不过第二种的设置我们还是需要了解的。第一种的代码可以在网上搜到,网址,reset.css,不用自己书写。
JS部分
function playSound(e) {
const keyCode = e.keyCode;
// 标签的数据属性
const key = document.querySelector(`
.key[data-key="${keyCode}"]
`)
key && key.classList.add('playing');
const keys = document.querySelectorAll('.key');
// console.log(keys)
keys.forEach((key) => {
key.addEventListener('transitionend', function (e) {
if (e.propertyName != 'transform') return;
this.classList.remove('playing');
})
})
const audio = document.querySelector(`
audio[data-key="${keyCode}"]
`)
audio.currentTime = 0;
audio.play();
}
window.addEventListener('keydown', playSound)
解释:
-
playSound
函数接受一个事件对象e
,代表键盘按下事件。- 通过
e.keyCode
获取按下的键码。 - 使用
document.querySelector
选择器找到拥有对应键码的.key
元素,并添加 ‘playing’ 类,触发样式效果。 - 通过
document.querySelectorAll
获取所有.key
元素,为每个元素添加transitionend
事件监听器,确保在过渡结束时移除 ‘playing’ 类。playing类为我们之前写的样式,点击某个按钮后会呈现一种放大的样式。 - 通过
document.querySelector
找到对应键码的音频元素,将音频的播放时间重置为 0,并播放音频。
-
window.addEventListener(‘keydown’, playSound):
- 将
playSound
函数绑定到全局window
对象的keydown
事件上,即当用户按下键盘上的任意键时,触发playSound
函数。
- 将
-
解释细节:
- 添加 ‘playing’ 类使得按下的键在页面上有一个瞬时的样式效果。
- 通过监听
transitionend
事件,确保样式效果在过渡结束后被移除,避免样式效果持续存在。 - 通过选择器找到对应的音频元素,将播放时间重置为 0,以确保每次按下键时都从音频的起始位置开始播放。
解释一下下面这段代码,可能有些人不太了解
keys.forEach((key) => {
key.addEventListener('transitionend', function (e) {
if (e.propertyName != 'transform') return;
this.classList.remove('playing');
})
})
key.addEventListener('transitionend', ...)
添加了一个事件监听器,用来监听过渡结束事件。e.propertyName
是用来检查触发过渡结束的 CSS 属性的名称。通过if (e.propertyName != 'transform') return;
判断只有当触发事件的属性是 ‘transform’ 时才执行后续的代码。这是因为键盘按键的样式变化主要涉及到 CSS 的 transform 属性。
留言
感兴趣的掘友们可以去试试哦。本人GitHub链接,里面有音频可以下载哦♥(ˆ◡ˆԅ)。
原文链接:https://juejin.cn/post/7312658500144300032 作者:全糖奶茶不加糖