使用jQuery单击另一个音频文件时停止/暂停音频

时间:2023-01-19 18:58:15

I have created a site with image thumbnails of people I have photographed. When a visitor clicks on one of the thumbnails the full image is revealed using jQuery, and an audio introduction plays. I have a different audio introduction for each thumbnail/image combination - 15 at present with more being added daily.

我创建了一个网站,其中包含我拍摄过的人的图像缩略图。当访问者点击其中一个缩略图时,使用jQuery显示完整图像,并播放音频介绍。我对每个缩略图/图像组合都有不同的音频介绍 - 目前有15个,每天添加更多。

I would like to ensure that if a visitor clicks on another thumbnail before the previous audio file has completed, that the previous audio file is stopped/paused to allow the new audio file to be played - thereby ensuring two or more tracks do not play simultaneously.

我想确保如果访问者在上一个音频文件完成之前点击另一个缩略图,则前一个音频文件被停止/暂停以允许播放新的音频文件 - 从而确保两个或多个轨道不能同时播放。

I am currently using the following snippet of code, wrapped in an anonymous function, to play each audio file individually when the appropriate thumbnail is clicked - so this snippet is duplicated for each audio file, but don't know how to ensure they do not play over one another.

我目前正在使用以下代码片段(包含在匿名函数中),在单击相应的缩略图时单独播放每个音频文件 - 因此每个音频文件都会复制此片段,但不知道如何确保它们不会相互比赛。

$(".bridget-strevens").click(function(){
  var audio = $('#bridget-strevens-intro')[0];
  if (audio.paused){
    audio.play();
  } else {
    audio.pause();
  }
});

Any help you could give me would be very grateful, as I am just starting to learn jQuery, and don't have the knowledge to come up with a workable solution.

你能给我的任何帮助都会非常感激,因为我刚开始学习jQuery,并且没有足够的知识来提出可行的解决方案。

Thanks in advance for your help!

在此先感谢您的帮助!

1 个解决方案

#1


Add a .audio class to all your audio elements and loop through all of them when an audio is clicked.

将.audio类添加到所有音频元素,并在单击音频时循环遍历所有音频元素。

$(".bridget-strevens").click(function () {
    $('.audio').each(function (index, value) {
        if (!value.paused) {
            value.pause();
        }
    });
    var audio = $('#bridget-strevens-intro')[0];
    if (audio.paused) {
        audio.play();
    } else {
        audio.pause();
    }
});

If that seems too heavy for you then simply add the audio element in a global variable such as:

如果这对您来说太沉重,那么只需将音频元素添加到全局变量中,例如:

var currentAudio;

Then when a new audio is clicked, simply pause that one, play the new one and update the currentAudio variable with the new element currently being played.

然后,当单击一个新音频时,只需暂停该音频,播放新音频并使用当前正在播放的新元素更新currentAudio变量。

var currentAudio = null;
$(".bridget-strevens").click(function () {
    if(currentAudio != null && !currentAudio.paused){
      currentAudio.pause();
    }
    var audio = $('#bridget-strevens-intro')[0];
    if (audio.paused) {
        audio.play();
        currentAudio = audio;
    } else {
        audio.pause();
    }
});

Update:

Thanks for the prompt responses! Grimbode, I've tried what you suggest, and that seems to work. However is there the ability to stop and reset rather than just pause - so if they clicked on 1 then [2] before 1 finished, then clicked 1 again, that 1 would start from the beginning again rather than the point at which it was paused? And is there any way of check the state 'globally', and then add code for each individual audio file - just to keep the amount of code and duplication down? Thanks again!! –

感谢您的快速回复! Grimbode,我已经尝试了你的建议,这似乎有效。但是有能力停止和重置而不是暂停 - 所以如果他们在1完成之前点击1然后[2],然后再次点击1,那1将从头开始而不是暂停的点?有没有办法检查状态'全局',然后为每个单独的音频文件添加代码 - 只是为了保持代码量和重复下来?再次感谢!! -

Yes. Play audio and restart it onclick explains in detail how to do this. The final result would look something like this:

是。播放音频并重新启动它点击详细说明如何执行此操作。最终结果看起来像这样:

var currentAudio = null;
$(".bridget-strevens").click(function () {
    if(currentAudio != null && !currentAudio.paused && currentAudio != this){
      currentAudio.pause();
      //Here we reset the audio and put it back to 0.
      currentAudio.currentTime = 0;
    }
    var audio = $('#bridget-strevens-intro')[0];
    if (audio.paused) {
        audio.play();
        currentAudio = audio;
    } else {
        audio.pause();
    }
});

You can't really optimize the code much more. You're going to have apply the click event on every audio element. You're going to have to keep the current playing audio element memorized so you don't have to loop through all the audio files.

你无法真正优化代码。您将在每个音频元素上应用click事件。您将不得不记住当前播放的音频元素,这样您就不必遍历所有音频文件。

If you really want to take this further you could create a library to handle everything. Here is an example:

如果你真的想进一步,你可以创建一个库来处理一切。这是一个例子:

(function(){
  var _ = function(o){
    if(!(this instanceof _)){
       return new _(o);
    }
    if(typeof o === 'undefined'){
       o = {};
    }

    //here you set attributes
    this.targets = o.targets || {};
    this.current = o.current || null;

  };

  //create fn shortcut
  _.fn = _.prototype = {
    init: function(){}
  }

  //Here you create your methods
  _.fn.load = function(){
    //here you load all the files in your this.targets.. meaning you load the source
    //OR you add the click events on them. 

    //returning this for chainability
    return this
  };

  //exporting
  window._ = _;
})();

//here is how you use it
_({
 targets: $('.audio')
}).load();

#1


Add a .audio class to all your audio elements and loop through all of them when an audio is clicked.

将.audio类添加到所有音频元素,并在单击音频时循环遍历所有音频元素。

$(".bridget-strevens").click(function () {
    $('.audio').each(function (index, value) {
        if (!value.paused) {
            value.pause();
        }
    });
    var audio = $('#bridget-strevens-intro')[0];
    if (audio.paused) {
        audio.play();
    } else {
        audio.pause();
    }
});

If that seems too heavy for you then simply add the audio element in a global variable such as:

如果这对您来说太沉重,那么只需将音频元素添加到全局变量中,例如:

var currentAudio;

Then when a new audio is clicked, simply pause that one, play the new one and update the currentAudio variable with the new element currently being played.

然后,当单击一个新音频时,只需暂停该音频,播放新音频并使用当前正在播放的新元素更新currentAudio变量。

var currentAudio = null;
$(".bridget-strevens").click(function () {
    if(currentAudio != null && !currentAudio.paused){
      currentAudio.pause();
    }
    var audio = $('#bridget-strevens-intro')[0];
    if (audio.paused) {
        audio.play();
        currentAudio = audio;
    } else {
        audio.pause();
    }
});

Update:

Thanks for the prompt responses! Grimbode, I've tried what you suggest, and that seems to work. However is there the ability to stop and reset rather than just pause - so if they clicked on 1 then [2] before 1 finished, then clicked 1 again, that 1 would start from the beginning again rather than the point at which it was paused? And is there any way of check the state 'globally', and then add code for each individual audio file - just to keep the amount of code and duplication down? Thanks again!! –

感谢您的快速回复! Grimbode,我已经尝试了你的建议,这似乎有效。但是有能力停止和重置而不是暂停 - 所以如果他们在1完成之前点击1然后[2],然后再次点击1,那1将从头开始而不是暂停的点?有没有办法检查状态'全局',然后为每个单独的音频文件添加代码 - 只是为了保持代码量和重复下来?再次感谢!! -

Yes. Play audio and restart it onclick explains in detail how to do this. The final result would look something like this:

是。播放音频并重新启动它点击详细说明如何执行此操作。最终结果看起来像这样:

var currentAudio = null;
$(".bridget-strevens").click(function () {
    if(currentAudio != null && !currentAudio.paused && currentAudio != this){
      currentAudio.pause();
      //Here we reset the audio and put it back to 0.
      currentAudio.currentTime = 0;
    }
    var audio = $('#bridget-strevens-intro')[0];
    if (audio.paused) {
        audio.play();
        currentAudio = audio;
    } else {
        audio.pause();
    }
});

You can't really optimize the code much more. You're going to have apply the click event on every audio element. You're going to have to keep the current playing audio element memorized so you don't have to loop through all the audio files.

你无法真正优化代码。您将在每个音频元素上应用click事件。您将不得不记住当前播放的音频元素,这样您就不必遍历所有音频文件。

If you really want to take this further you could create a library to handle everything. Here is an example:

如果你真的想进一步,你可以创建一个库来处理一切。这是一个例子:

(function(){
  var _ = function(o){
    if(!(this instanceof _)){
       return new _(o);
    }
    if(typeof o === 'undefined'){
       o = {};
    }

    //here you set attributes
    this.targets = o.targets || {};
    this.current = o.current || null;

  };

  //create fn shortcut
  _.fn = _.prototype = {
    init: function(){}
  }

  //Here you create your methods
  _.fn.load = function(){
    //here you load all the files in your this.targets.. meaning you load the source
    //OR you add the click events on them. 

    //returning this for chainability
    return this
  };

  //exporting
  window._ = _;
})();

//here is how you use it
_({
 targets: $('.audio')
}).load();