Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/514.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何防止音频重叠?_Javascript_Html - Fatal编程技术网

Javascript 如何防止音频重叠?

Javascript 如何防止音频重叠?,javascript,html,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

我有一个简单的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>

该函数只从单击的元素中获取
dataset
值并播放音频。这很好,但是如果我快速连续多次单击一个div,或者在上一个音频仍在播放时单击另一个元素,则音频的播放会相互重叠。我还尝试添加了
stopPropagation()
函数,但没有成功。这里怎么了?

您应该检查音频是否正在播放,如果正在播放,就不要播放下一个声音。 我修改了您的代码以实现此目的:

function play(mp3) {
  if (!playing.paused) {
    return;
  }
  mp3.play();
  playing = mp3;
}
$('.AR').on('click', function () {

  // 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 = audio_file;

  if (!e.mp3) {
    e.mp3 = new Audio(audio_url);
  }

  play(e.mp3);

});
这里有一个现场演示:

实现这一点的方法有很多

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

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

$(“.AR”)
.each(函数({
/*
对于每个.AR元素,预加载并实例化
音频对象。关联音频实例
使用此元素(通过“音频对象”数据键)
*/
$(this).data('audio-object',new audio());
})
.on('click',函数(e){
/*
单击.AR元素时,迭代所有.AR
元素,并暂停/重置相关音频
实例(如果音频具有src属性)。
这具有“停止所有音频”的效果
.AR页面上的元素
*/
$('.AR')。每个(函数(){
var audio=$(this).data('audio-object');
if(audio.src){
audio.pause();
audio.currentTime=0;
}
});
/*
现在.AR元素的所有音频对象
已停止播放,开始实际播放
已单击的.AR元素的音频对象。
如果音频对象没有src属性,请指定
加载此音频对象实例。
*/
var clickedAudio=$(this.data('audio-object');
如果(!clickedAudio.src){
单击audio.src=$(this.data('audio');
}
单击音频播放();
});

文本1
文本2
文本3

stopPropagation对多次单击不同的元素没有任何作用。您需要检测当前是否正在播放某个声音,然后排队等待下一个声音或阻止它完全播放。这非常有效!谢谢!然而,有没有一种方法,如果我点击一个新元素,先前的音频停止播放,新的音频开始播放?你的代码工作得很好,并且实现了我从其他注释中想要的功能。然而,有一个问题。此代码预加载页面上的所有mp3文件重新加载。例如,如果我有200个这样的元素,这个函数会一次自动下载所有的mp3,然后从缓存中播放它们。这不是我想要的,因为最终我将拥有更多的元素。有什么解决办法吗?@MarwanAnsari刚刚更新了答案-这有帮助吗?您更新的代码工作得非常好!非常感谢你帮助我:)
function play(mp3) {
  if (!playing.paused) {
    return;
  }
  mp3.play();
  playing = mp3;
}
$('.AR').on('click', function () {

  // 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 = audio_file;

  if (!e.mp3) {
    e.mp3 = new Audio(audio_url);
  }

  play(e.mp3);

});