实现效果

实现思路

  • 一共要实现两个功能:

    • 按下键盘A-L的某一个键就播放对应的音频

      • 实现这个功能需要监听键盘按下的事件,用到onkeydown事件

        • 可以在控制台打印一下window,会看到他里面自带了很多的事件(以on开头)
      • 要实现按下按键A,然后对应的方块A就播放音频,就需要给每一个方块绑定按键A-L对应的编号

        • 比如,给方块A添加onkeydown事件后,打印一下event,可以看到event对象里有一个keyCode属性,这个属性对应的按键A的值为65

          • 专门查按键对应的keyCode的网站:JavaScript Event keyCodes
        • 可以把这个65通过html的自定义属性data-*绑定到方块A上,这样在获取元素的时候直接通过event.keyCode获取到对应的元素

        • 获取到对应的音频元素后,使用play()方法播放音频

          • 这里需要注意,当按下了A-L以外的按键时,得到的audio是为空的,会报错,所以需要进行判断,为空的话就直接return,结束掉这个onkeydown事件函数,不在往下执行

          • 这里还有一个问题就是,当我们连续按下通过一个按键时,他并不是每次都从头开始播放的,而是等上一下播放结束,所以音频播放的次数,跟按键按下的次数是不相等的。可以手动将Audio对象的currentTime属性设置为0,实现每次按下按键都从头开始播放音频

            • 执行一下console.log([audio]);,可以看到他里面包含currentTime这个属性
            • currentTime 属性设置或返回视频播放的当前位置(以秒计),当设置该属性时,播放会跳跃到指定的位置。
          <div data-key="65" id="clap" class="btn"><kbd>A</kbd><span>CLAP</span>
          </div>
          <audio data-key="65" src="sounds/clap.wav"></audio>
          
          window.addEventListener('keydown', function(event){var audio = document.querySelector(`audio[data-key="${event.keyCode}"]`);var btn = document.querySelector(`div[data-key="${event.keyCode}"]`);// console.log([audio]);// 如果按下的是其他的键,就直接returnif (!audio) return;audio.currentTime = 0;audio.play();})
          
    • 按下按键后会有一个边框样式变化的特效,而且是一闪而过的

      • 当按下按键时,就给对应的方块添加类名playing,从而实现边框样式的变化

        .playing {transform:scale(1.1);border-color:#ffc600;box-shadow: 0 0 10px #ffc600;
        }
        
      • 样式一闪而过的效果:

        • 给每一个方块添加transition属性,实现从样式a到样式b变化过渡

        • 对这个过渡的过程进行监听,使用transitionend事件,在过渡完成后就删除类名playing,从而移除样式

        • transitionend事件函数里打印一下event,会看到他监听了方块上所有的属性,这是因为我设置的transition值为all .07s ease;all就代表方块设置的所有样式属性

        • 但是我们只需要监听到transform属性,所以使用event.propertyName过滤掉其他的属性事件

          //获取元素
          // 使用`Array.from()`将类数组转换为数组
          var btns = Array.from(document.querySelectorAll('.btn'));btns.forEach(item => item.addEventListener('transitionend', function(event){if (event.propertyName !== 'transform') return; // 过滤其中一种事件    event.target.classList.remove('playing')
          }));
          

完整代码

<!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>DrumKit</title><style>*,html,body{padding: 0;margin: 0;height: 100%;}#main{width: 100%;height: 100%;display: flex;justify-content: space-evenly;align-items: center;}kbd{height: auto;font-size: 2.125rem;font-weight: 700;}span{height: auto;display: block;font-size: 0.75rem;color: #ffc600;margin-top: 4px;}.btn{width: 100px;height: 100px;text-align: center;border: 6px solid #333;border-radius: 6px;box-sizing: border-box;padding: 12px;cursor: pointer;transition:all .07s ease;}audio{display: none;}.playing {transform:scale(1.1);border-color:#ffc600;box-shadow: 0 0 10px #ffc600;}</style>
</head>
<body><div id="main"><div data-key="65" id="clap" class="btn"><kbd>A</kbd><span>CLAP</span></div><div data-key="83" id="hihat" class="btn"><kbd>S</kbd><span>HIHAT</span></div><div data-key="68" id="kick" class="btn"><kbd>D</kbd><span>KICK</span></div><div data-key="70" id="openhat" class="btn"><kbd>F</kbd><span>OPENHAT</span></div><div data-key="71" id="boom" class="btn"><kbd>G</kbd><span>BOOM</span></div><div data-key="72" id="ride" class="btn"><kbd>H</kbd><span>RIDE</span></div><div data-key="74" id="snare" class="btn"><kbd>J</kbd><span>SNARE</span></div><div data-key="75" id="tom" class="btn"><kbd>K</kbd><span>TOM</span></div><div data-key="76" id="tink" class="btn"><kbd>L</kbd><span>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>// 按照目标要求,我们要实现按下按键A-L对应的方块就能发出对应的声音// 那么代码就需要实现两个部分// 1. 按下按键音频能够播放 --> 解决怎么知道按下A要播放那个音频? --> // 解决办法:按下按键触发事件,那必然用到`onkeydown`键盘事件,这个事件有一个属性`keyCode`记录着每一个按键对应的编码// 将这个编码绑定到音频标签上(使用HTML自定义属性`data-*`),这样每次按下按键A,就获取A对应编码的音频,调用`play()`函数,播放他即可// 2. 播放音频的同时方块边框有特效并且播放结束特效消失 --> 解决如何实现播放结束特效就消失 -->// 解决办法:一播放方块边框样式就要变化,那么就事先写好一个样式,并且也给方块绑定按键编码,一按下按键就给边框添加样式// 给边框样式变化前后添加一个过渡属性`transition`,监听这个过渡的过程,过渡一完成就移除添加的样式// 实现// 需求1:按下按键音频能够播放window.addEventListener('keydown',function(event){// 根据keyCode获取对应的音频元素和方块元素const btn = document.querySelector(`div[data-key="${event.keyCode}"]`);const audio = document.querySelector(`audio[data-key="${event.keyCode}"]`);// 避免按下除A-L以外的按键抛出错误,当遇到audio为空时,直接结束函数if (!audio) return;// 设置每次按下按键音频都从头开始播放audio.currentTime = 0;// 播放音频audio.play();// 给方块添加样式btn.classList.add('playing');});// 需求2:播放音频的同时方块边框有特效并且播放结束特效消失// 获取所有的方块const btns = [...document.querySelectorAll('.btn')];btns.forEach(item => item.addEventListener('transitionend', function(event){if (event.propertyName !== 'transform') return;event.target.classList.remove('playing');}))// 实现点击方块播放音频const audios = document.querySelectorAll('audio');for (let i = 0; i < btns.length; i++) {btns[i].addEventListener('click', function(){// 设置每次按下按键音频都从头开始播放audios[i].currentTime = 0;// 播放音频audios[i].play();// 给方块添加样式this.classList.add('playing');})}</script>
</body>
</html>

Day1 - 原生JavaScript实现打击鼓相关推荐

  1. 分享10个原生JavaScript技巧

    首先在这里要非常感谢无私分享作品的网友们,这些代码片段主要由网友们平时分享的作品代码里面和经常去逛网站然后查看源文件收集到的.把平时网站上常用的一些实用功能代码片段通通收集起来,方便网友们学习使用,利 ...

  2. animate用法 js原生_用 原生Javascript 创建带动画的固顶导航菜单

    当我们在网页中加入一个导航菜单的时候,需要考虑很多因素.如何确定它的位置?如何定义样式?还需要保证它具有良好的响应性.又或者你想为它添加一些炫酷的动画.这时你可能会对 jQuery 感兴趣,因为它会帮 ...

  3. mysql插入ㄖ_原生JavaScript代码100个实例

    1.原生JavaScript实现字符串长度截取 function cutstr(str, len) { var temp; var icount = 0; var patrn = /[^\x00-\x ...

  4. java文件异步上传_[Java教程]原生javascript实现文件异步上传

    [Java教程]原生javascript实现文件异步上传 0 2017-10-25 19:00:06 效果图: 代码:(demo33.jsp) demo33.jsp名称文件确定 本文网址:http:/ ...

  5. [译] 原生 JavaScript 值得学习吗?答案是肯定的

    原文地址:Is Vanilla JavaScript worth learning? Absolutely. 原文作者:David Kopal 译文出自:掘金翻译计划 本文永久链接:github.co ...

  6. React jsx转换成原生JavaScript的一个例子

    jsx代码: var React = require('react'); var ReactDOM = require('react-dom'); var MyButtonController = r ...

  7. 原生希望原生JavaScript开篇

    本篇文章个人在深圳游玩的时候突然想到的...最近就有想写几篇关于原生希望的文章,所以回家到之后就奋笔疾书的写出来发布了 一直对前端技巧很有兴致,就心生了写一个专栏的动机,然后就申请了原生JavaScr ...

  8. 一些常用且实用的原生 JavaScript函数[转]

    日常开始中常用到的一些原生JavaScript函数,比较实用, 今天特地整理一下,分享给大家,希望对大家有用,会常更新,同时也欢迎大家补充. css及html方面的技巧总结,点此前往: 前端开发中一些 ...

  9. 原生JavaScript轮播图效果实现

    原生JavaScript实现轮播图切换效果的实现过程 本文所用代码仅供个人学习.此部分代码系按原腾讯电脑管家首页的轮播图效果,采用原生JS技术予以实现(原网页采用jQurey等技术). 1. 文件准备 ...

最新文章

  1. 科技和法律的碰撞——人脸识别为何在旧金山被叫停
  2. 灵光一现的trick
  3. C++paranthesis matching括号匹配的算法(附完整源码)
  4. git gui 历史版本_这些Git命令都不会,还是不要去面试了
  5. win2003 sp2+iis 6.0上部署.net 2.0和.net 4.0网站的方法
  6. mysql导入工具 行提交_使用命令行工具mysqlimport导入数据
  7. 如何击败腾讯_要击败这个新的电子游戏,请对其重新编程
  8. Spring Security——异常信息本地化
  9. 【OpenCV应用】python处理行李图像匹配项目——图像(简单)清晰化
  10. 神经网络入门之DNN(一)
  11. 菜鸟电子面单,自定义区设置方法
  12. 支付宝第三方登录接口调用
  13. 微信小程序把view居中_微信小程序view居中
  14. 10个免费图片站点(2020年最新)
  15. redis streams_如何构建Redis Streams应用程序
  16. 解决各种中文乱码问题
  17. 19年全国电赛 H题电磁炮硬件电路+可控硅
  18. 福特FORD EDI需求分析
  19. 离散数学真值表(c语言编程实现),C语言 实现离散数学合式公式真值表
  20. 计算机外围设备的一般功能

热门文章

  1. 【from zero to zero】noip2017
  2. python3基础入门巩固94题--源自github
  3. 中国硬质合金市场需求调研与前景预测分析报告2022年版
  4. ubuntu 下载百度网盘文件
  5. Linux应用层例程3 输入设备应用编程
  6. 卸载了Realtek Audio,扬声器没有声音
  7. ITextRenderer将多个页面导在一个pdf中
  8. 数据结构 二叉树 增 删 遍历 查询 实现 源码
  9. Shellshock漏洞回顾与分析测试
  10. HITCON 2015 lalala(SSRF)