如何阻止音频重叠?

时间:2019-01-24 23:31:48

标签: javascript html

我有一个简单的javascript函数,当我单击一个单词时会播放音频文件。这是HTML代码:

<div class="word">

  <div class="AR" data-audio="1.mp3">text 1</div>
  <div class="AR" data-audio="2.mp3">text 2</div>
  <div class="AR" data-audio="3.mp3">text 3</div>

</div>

这是JavaScript代码:

$('.AR').on('click', function (e) {

  // Stopping the audio from overlapping
  var e = event || window.event;
  e.cancelBubble = true;
  if (e.stopPropagation) e.stopPropagation();

  var this_element = event.target || event.srcElement;
  var audio_file = this_element.dataset.audio;
  var audio_url = "https://example.com/" + audio_file;

  if (e.mp3) {
    if(e.mp3.paused) e.mp3.play();
    else e.mp3.pause();
  } else {
      e.mp3 = new Audio(audio_url);
      e.mp3.play();
  }

});

该函数仅从单击的元素获取dataset值并播放音频。这项工作正常,但是如果快速连续单击div一次,或者在上一个音频仍在播放时单击另一个元素,则音频的播放会相互重叠。我也尝试过添加stopPropagation()函数,但是没有用。怎么了?

2 个答案:

答案 0 :(得分:1)

您应该检查音频是否正在播放,如果正在播放,请不要播放下一个声音。 我已经更改了您的代码来做到这一点:

await null;

这是一个现场演示: http://plnkr.co/edit/5orIJefLP7q6ufeTJ6fq?p=preview

答案 1 :(得分:1)

有很多方法可以实现。

一种方法是通过jQuery的Audio方法将.AR对象与.data()类的每个DIV元素相关联。对于所有通过.AR方法与.each()选择匹配的元素,可以将其关联为初始化步骤。

然后可以更新您的click逻辑,以便与.AR元素关联的所有音频对象在开始播放被单击的元素之前都被暂停和停止-这样可以避免“重叠音频”效应您注意到了:

$('.AR')
.each(function() {
  
  /*
  For each .AR element, preload and instantiate
  an audio object. Associate the audio instance
  with this element (via "audio-object" data key)
  */
  $(this).data('audio-object', new Audio());
  
})
.on('click', function (e) {
  
  /*
  When .AR element is clicked, iterate all .AR
  elements, and pause/reset the associated audio 
  instances (if audio has src attribute).
  This has the effect of "stopping all audio" for
  .AR elements on the page
  */
  $('.AR').each(function() {
    var audio = $(this).data('audio-object');

    if(audio.src) {
      audio.pause();
      audio.currentTime = 0;
    }
  });
  
  /*
  Now that all audio objects for .AR elements 
  have stopped playing, start playing the actual
  audio object for the .AR element that was clicked.

  If the audio object has no src attribute, assign
  to load this audio object instance.
  
  */
  var clickedAudio = $(this).data('audio-object');

  if(!clickedAudio.src) {
    clickedAudio.src = $(this).data('audio');
  }

  clickedAudio.play();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>

<div class="word">

  <div class="AR" data-audio="https://www.w3schools.com/html/horse.mp3">text 1</div>
  <div class="AR" data-audio="https://www.w3schools.com/html/horse.mp3">text 2</div>
  <div class="AR" data-audio="https://www.w3schools.com/html/horse.mp3">text 3</div>

</div>