Open Eye Media
Open Eye Media

Reputation: 13

Stopping/Pausing audio when another audio file is clicking using jQuery

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.

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.

Thanks in advance for your help!

Upvotes: 1

Views: 2103

Answers (1)

kockburn
kockburn

Reputation: 17616

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

$(".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.

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

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.

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();

Upvotes: 2

Related Questions