JavaScript30_01 - JavaScript Drum Kit

实现效果

模拟一个打鼓的页面。用户在键盘上按下 ASDFGHJKL 这几个键时,页面上与字母对应的按钮变大变亮,对应的鼓点声音响起来。

查看在线效果
在这里插入图片描述
码云Git仓库

基础语法

  • Array.from():从一个类似数组或者可迭代对象中创建一个新的,浅拷贝的数组实例

事件:

  • transitionend —— 在CSS transition过渡完成之后触发

  • event.propertyName —— 当发生transitionend事件时,这个属性返回与转换关联的CSS属性名称,只读

  • event对象属性

  • 修改DOM中的class

    • domObj.classList.add(“playing”)
    • domObj.classList.remove(“playing”)
  • jQuery修改class

    • domObj.addClass() 一个或多个
    • domObj.removeClass() 移除
    • domObj.hasClass()
    • $(“#xxx”).attr(“class”,”className”)
    • $(“#xxx”).removeAttr(“class”,”className”)
  • 绑定事件
    keys.addEventListener(“transitionend”,removeTransition)

  • 绑定keydown事件的时候,直接在window对象上绑定,而无需在每个键对应的对象上绑定。

  • 对一个数组中的对象绑定事件

    • keys.forEach(key => return key.addEventListener(“transitionend”,removeTransition));
    • 使用箭头函数简写,除了正常的返回值以外,简单的执行语句也可以放在返回处执行。

媒体控制:
audio.currentTime = 0; // 每次播放之后都使音频播放进度归零
audio.currentTime:已经播放的秒数

audio.play(); // 播放相应音效

分析

  • 按钮按下,播放对应音频,通过添加类名实现按键样式的变化
  • 样式变化完成后,触发transitionend事件,移除类名,将样式变回原样

实现:

HTML结构:


  <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>


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:4px solid black;
  border-radius:5px;
  margin:1rem;
  font-size: 1.5rem;
  padding:1rem .5rem;
  transition:all .07s;
  width:100px;
  text-align: center;
  color:white;
  background:rgba(0,0,0,0.4);
  text-shadow:0 0 5px black;
}

.playing {
  transform:scale(1.1);
  border-color:#ffc600;
  box-shadow: 0 0 10px #ffc600;
}

kbd {
  display: block;
  font-size: 40px;
}

.sound {
  font-size: 1.2rem;
  text-transform: uppercase;
  letter-spacing: 1px;
  color:#ffc600;
}

原生JS代码:

  <script>
@@@ 页面绑定键盘按下事件,触发事件后执行playSound方法,根据键码播放声音
    window.addEventListener("keydown",playSound);
    
@@@ 为每个按键绑定transitionend事件,过渡动画完成后,执行removeTransition方法。移除类名
    const keys = document.querySelectorAll(".key");
    keys.forEach(key => {
        key.addEventListener("transitionend",removeTransition)
    });



    function removeTransition(event){
        // 为什么要筛选一下?不是只有transitionend触发才会进入这个函数么
        if(event.propertyName !== 'transform') return;
@@@ 通过移除类名将元素样式变为原装
        event.target.classList.remove('playing')

    }

@@@ 通过键码找到对应元素,播放声音并添加playing类名更改样式
    function playSound(event){
  const audio = document.querySelector(`audio[data-key="${event.keyCode}"]`); // 根据触发按键的键码,获取对应音频
        const key = document.querySelector(`div[data-key="${event.keyCode}"]`); // 获取页面对应按钮 DIV 元素
        if (!audio) return; // 处理无效的按键事件

        key.classList.add('playing'); // 改变样式
        audio.currentTime = 0; // 每次播放之后都使音频播放进度归零
        audio.play(); // 播放相应音效
    }

  </script>


jQuery代码


  $(window).on('keydown',playSound);
  $(".key").on("transitionend",e=>{

      e.target.classList.remove('playing');
  });


  function playSound(e){
      const audio = $(`audio[data-key="${e.keyCode}"]`)[0];
      const key = $(`div[data-key="${e.keyCode}"]`)[0];

      if(!audio) return;

      key.classList.add('playing');
        audio.currentTime=0;
        audio.play()

  }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值