github rss
Day1 JavaScript Drum Kit
Dec 21, 2017
One minute read

创建页面及样式

创建index.html

涉及到的知识点:

data-

data-* 全局属性 构成一类称为自定义数据属性的属性,允许通过脚本在HTML 和其 DOM 表示之间交换专有信息。所有这些自定义数据都可以通过属性设置的元素的 HTMLElement 接口来访问。

HTMLElement.dataset 属性可以访问它们。 * 可以使用遵循 xml名称生产规则 的任何名称来被替换,并具有以下限制:

该名称不能以xml开头,无论这些字母用于什么情况; 该名称不能包含任何分号 (U+003A); 该名称不能包含A至Z的大写字母。 注意,HTMLElement.dataset 属性是一个StringMap,并且自定义数据属性 data-test-value 可以通过 HTMLElement.dataset.testValue ( 或者是 HTMLElement.dataset[“testValue”] ) 来访问,任何破折号(U+002D) 都会被下个字母的大写替代(驼峰拼写)。

参考 MDN: data-*

<kbd>

HTML键盘输入元素() 用于表示用户输入,它将产生一个行内元素,以浏览器的默认monospace字体显示。

<kbd>cmd</kbd>

参考 MDN: kbd

创建index.css

涉及到的知识点:

CSS 长度值

单位 含义
em 相对于父元素的字体大小
ex 相对于小写字母”x”的高度
rem 相对于根元素字体大小
vw 相对于视窗的宽度:视窗宽度是100vw
vh 相对于视窗的高度:视窗高度是100vh
vm 相对于视窗的宽度或高度,取决于哪个更小
% 相对于父元素。正常情况下是通过属性定义自身或其他元素

vwvh 称为视口单位,允许我们更杰基恩浏览器窗口定义的大小

在桌面端,视口指的是在桌面端,指的是浏览器的可视区域;而在移动端,它涉及3个视口:Layout Viewport(布局视口),Visual Viewport(视觉视口),Ideal Viewport(理想视口)。

视口单位中的“视口”,桌面端指的是浏览器的可视区域;移动端指的就是Viewport中的Layout Viewport。

添加 JS 代码

监听按键 & 添加动画 & 音效播放

  • 监听页面的 keydown 事件,触发 playAudio 函数
window.addEventListener('keydown', playSound);
  • key 添加动画

    1. 怎么监听我们按了哪个按键呢?每一个按键都有自己的KeyCode,我们通过按键的KeyCode来判断

    2. 在这里我们用到了ES6的模板字符串,${e.keyCode},可以动态的将按键的Keycode传过去,以使audio动态的获取每一个按键绑定的 audio。需要注意的是模板字符串一定要使用”`“(Esc下面那个键)包裹,而不是双引号。

    3. key 添加 playing 类,展示小动画

const key = document.querySelector(`div[data-key="${e.keyCode}"]`);
if(!key) return;
key.classList.add('playing');
  • audio 添加播放

    1. 我们注意到 audio.play();前面一行是audio.currentTime = 0;,这是因为,如果没有在播放音效前将该音乐重置,会发生以下情况,当我连续点击某一按键的时候,只有第一次点击会响,第二次第三次连续的点击可能没声音。所以在每一次点击之前重置音效是很有必要的。

    2. play() 方法开始播放当前的音频或视频。

const audio = document.querySelector(`audio[data-key="${e.keyCode}"]`);
if (!audio) return;
audio.currentTime = 0;
audio.play();

动画结束后移除动画

  • 监听每一个按键元素的ttransitionend事件,当按键元素的动画结束后会触发stopTransition函数。

transitionend 事件会在 CSS transition 结束后触发. 当transition完成前移除transition时,比如移除css的transition-property 属性,事件将不会被触发.如在transition完成前设置 display 为”none”,事件同样不会被触发。

  • 首先在removeTransition函数中可以输出事件e的内容,会输出该动画每一步具体的变化,发现其中会有propertyName属性,可以通过判断propertyName等于其中的一个值(例如’transform’),等于该值就移除playing类,也即移除动画。

propertyName: The name of the CSS property associated with the transition.

  • 在定位元素的时候,可以使用this也可以使用e.target,可以简单这么理解,this值的是谁出发了这次事件,也就是key,就等同于事件的目标(e.target)。
function removeTransition(e) {
    if (e.propertyName !== 'transform') return;
    e.target.classList.remove('playing');
  }
  • 解除绑定 选取 class 为 key 的每个元素,然后使用 Array.from 方法创建一个新数组,再使用 forEach 方法遍历该数组,添加监听事件,一旦动画结束,就执行移除动画事件

Array.from: 从一个类似数组或可迭代对象中创建一个新的数组实例

forEach:对数组的每个元素执行一次提供的函数

const keys = Array.from(document.querySelectorAll('.key'));
keys.forEach(key => key.addEventListener('transitionend', removeTransition));

完整代码戳我的 lttxzmj GitHub,欢迎 star。


Back to posts