Day01 – JavaScript Drum Kit 中文指南
作者:©liyuechun
简介:JavaScript30 是 Wes Bos 推出的一个 30 天应战。项目免费供应了 30 个视频教程、30 个应战的肇端文档和 30 个应战处理方案源代码。目的是协助人们用纯 JavaScript 来写东西,不借助框架和库,也不运用编译器和援用。如今你看到的是这系列指南的第 1 篇。完全指南在 从零到壹全栈部落。
简介
第一天的演习是用JS制造一个爵士鼓的页面,经由过程敲击键盘上差别的字母,会发出差别的声响,而且页面上会伴随着敲击的动画。
结果以下:
想要完成以上结果,大抵思绪和处理方案以下:
检测到键盘上什么键被按下–监听
keydown
事宜在按键被按下的时刻,播放音效–
audio.play()
在按键被按下的同时,播放动画–
Element.classList.add('playing')
在动画完毕后,移除动画,不然以后再点击不会有任何结果–
Element.classList.remove('playing')
基本语法
一些 ES6 语法
const
:声明一个只读的常量,标识符的值只能赋值一次。`字符串 ${ 变量、属性名 } `:模板字面量(Template literals)中用于示意模板字符串的标识。特点是字符串首尾用反引号(`),内部的模板部分用 ${ } 括起来示意,详细请看MDN文档。简朴例子以下:
var a = 1;
var b = 2;
//不必模板的写法
console.log("三是" + (a + b) + "不是" + (2 * a + b)); //"三是3不是4"
//运用模板字符串的写法
console.log(`三是${a + b}不是${2 * a + b}`); //"三是3不是4"
forEach
与箭头函数
运用 document.querySelector
猎取一组相符 CSS 选择符的元素快照,范例为 NodeList(此对象是关于文档的实时运转的动态查询),对其举行遍用时可采用 forEach
要领。
// Code from http://es6-features.org/#StatementBodies
// ES6
nums.forEach(v => {
if (v % 5 === 0)
fives.push(v);
})
// ES5
nums.forEach(function (v) {
if (v % 5 === 0)
five.push(v);
})
页面基本规划
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JS Drum Kit</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="keys">
<div data-key="65" class="key">
<kbd>A</kbd>
<span class="sound">clap</span>
</div>
<div data-key="83" class="key">
<kbd>S</kbd>
<span class="sound">hihat</span>
</div>
<div data-key="68" class="key">
<kbd>D</kbd>
<span class="sound">kick</span>
</div>
<div data-key="70" class="key">
<kbd>F</kbd>
<span class="sound">openhat</span>
</div>
<div data-key="71" class="key">
<kbd>G</kbd>
<span class="sound">boom</span>
</div>
<div data-key="72" class="key">
<kbd>H</kbd>
<span class="sound">ride</span>
</div>
<div data-key="74" class="key">
<kbd>J</kbd>
<span class="sound">snare</span>
</div>
<div data-key="75" class="key">
<kbd>K</kbd>
<span class="sound">tom</span>
</div>
<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="83" src="sounds/hihat.wav"></audio>
<audio data-key="68" src="sounds/kick.wav"></audio>
<audio data-key="70" src="sounds/openhat.wav"></audio>
<audio data-key="71" src="sounds/boom.wav"></audio>
<audio data-key="72" src="sounds/ride.wav"></audio>
<audio data-key="74" src="sounds/snare.wav"></audio>
<audio data-key="75" src="sounds/tom.wav"></audio>
<audio data-key="76" src="sounds/tink.wav"></audio>
<script>
</script>
</body>
</html>
标签定义键盘文本
说到手艺概念上的特别款式时,就要提到 标签。正如你已猜到的,它用来示意文本是从键盘上键入的。
浏览器通常常使用等宽字体来显现该标签中包括的文本。
标签经常常使用在于计算机相干的文档和手册中。比方:
键入 <kbd>quit</kbd> 来退出顺序,或许键入 <kbd>menu</kbd> 来返回主菜单。
运用 data-* 属性来嵌入自定义数据
页面里经由过程data-key将页面展现的内容和audio关联起来。运用要领以下引见:
<ul>
<li data-animal-type="bird">Owl</li>
<li data-animal-type="fish">Salmon</li>
<li data-animal-type="spider">Tarantula</li>
</ul>
① data-* 属性用于存储页面或应用顺序的私有自定义数据。
② data-* 属性给予我们在所有 HTML 元素上嵌入自定义 data 属性的才能。
③ 属性名不应该包括任何大写字母,而且在前缀 “data-” 以后必须有最少一个字符
④ 属性值可所以恣意字符串
语法:
<element data-*="somevalue">
属性值:
值 | 形貌 |
---|---|
somevalue | 划定属性的值(以字符串)。 |
重要CSS代码
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;
align-items: center;
justify-content: center;
}
.key {
border: .4rem solid black;
border-radius: .5rem;
margin: 1rem;
font-size: 1.5rem;
padding: 1rem .5rem;
transition: all .07s ease;
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;
}
重要属性有以下几个:
html
中有一个款式为font-size: 10px;
,在本案例中,1rem
就是10px,rem是以html中的font-size
为参照物,1.2rem
就是12px
。transform: scale(1.1);
–该属性在键盘被点击时将该元素缩放至本来的1.1倍。.key{border: .4rem solid black;} .playing{border-color: #ffc600;}
–这两条属性在按键点击的时刻转变边框色彩。.key{text-shadow: 0 0 .5rem black;} .playing{box-shadow: 0 0 1rem #ffc600;}
–这两条属性在按键点击的时刻转变暗影的结果transition: all .07s ease;
–定义以上动画在0.07秒内完成。
我们注重到我们定义了.palying
类,在按键按下的时侯为该元素增加playing
类,在完毕后移除playing
类。
JS代码
按键监听&音效播放&增加动画
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();
}
/**
* 监听页面的keydown事宜,触发playAudio函数。
*/
window.addEventListener('keydown', playSound);
监听页面的keydown事宜,触发playAudio函数。
经由过程KeyCode检测我们按下的键盘按钮是哪一个按钮。
A -> 65
B -> 66
C -> 67
D -> 68
E -> 69
F -> 70
G -> 71
H -> 72
I -> 73
J -> 74
K -> 75
L -> 76
M -> 77
N -> 78
O -> 79
P -> 80
Q -> 81
R -> 82
S -> 83
T -> 84
U -> 85
V -> 86
W -> 87
X -> 88
Y -> 89
Z -> 90
http://keycode.info翻开这个网站,能够轻松检察键盘的按钮对应的code。
在这里我们用到了ES6的模板字符串,
${e.keyCode}
,能够动态的将按键的Keycode
传过去,以使audio
动态的猎取每个按键绑定的audio
。须要注重的是模板字符串一定要运用”`”(Esc下面谁人键)包裹,而不是双引号。我们注重到
audio.play();
前面一行是audio.currentTime = 0;
,这是由于,假如没有在播放音效前将该音乐重置,会发作以下状况,当我一连点击某一按键的时刻,只要第一次点击会响,第二次第三次一连的点击能够没声响。所以在每一次点击之前重置音效是很有必要的。key.classList.add('playing');
能够在按键点击的同时为该元素增加playing类,展现小动画。if(!audio) return; if(!key) return;
由于并非每个按键都有音效,当用户点击了非绑定音效按键,实时退出函数是很好的习气。
动画完毕后移除动画
function stopTransition(e) {
if (e.propertyName !== 'transform') return;
e.target.classList.remove('playing');
}
const keys = Array.from(document.querySelectorAll('.key'));
keys.forEach(key => key.addEventListener('transitionend',stopTransition));
监听每个按键元素的
transitionend
事宜,当按键元素的动画完毕后会触发stopTransition
函数。首先在
stopTransition
函数中能够输出事宜e的内容,会输出该动画每一步详细的变化,发明个中会有propertyName
属性,能够经由过程推断propertyName
即是个中的一个值(比方’transform’),即是该值就移除playing
类,也即移除动画。在定位元素的时刻,能够运用
this
也能够运用e.target
,能够简朴这么明白,this
值的是谁出发了此次事宜,也就是key
,就等同于事宜的目的(e.target).
处理难点
怎样将键盘按键与页面按钮对应起来?
衔接的帮手是 keydown
事宜中的 keyCode
属性,keyCode
属性的值和 ASCII 编码值雷同(对应小写字母)。在这个网站能够用按键盘来检察对应的键码。
我们能猎取到的初始页面中,按钮 div
和音频 audio
标签中都增加了一个属性 data-key
用于存储对应的键码,如许做的目的是,增加键盘事宜监听后,触发键盘事宜时即可猎取事宜的 keyCode
属性值,以此为线索,操纵对应的按钮及音频。
const audio = document.querySelector(`audio[data-key="${e.keyCode}"]`);
const key = document.querySelector(`div[data-key="${e.keyCode}"]`);
怎样保证按键被按住不放时,能够立时响起一连鼓点声?
每次播放音频之前,设置播放时候戳为 0:
const audio = document.querySelector(`audio[data-key="${e.keyCode}"]`);
audio.currentTime = 0;
audio.play();
怎样使页面按钮恢复原状?
应用一个叫 transitionened
的事宜,它在 CSS transition 完毕后会被触发。我们就能够应用这个事宜,在每次打鼓的结果(尺寸变大、色彩变化)完成以后,去除响应款式。
在这个页面中,发作 transition
的款式属性不止一个(box-shadow
, transform
, border-color
),所以须要增加一个推断语句,使每发作一次按键事宜时,只去除一次款式。
funciton remove(event) {
if (event.propertyName !== 'transform') return;
this.classList.remove('playing');
// event.target.classList.remove('playing');
}
完全源码
扫码申请加入全栈部落 |
---|