DannyBoy DannyBoy - 5 months ago 14
jQuery Question

How to have multiple player instances from the same plugin

I am trying to create a music player plugin, in which there will be multiple instances of it within the same page. The Audio object will be the same for all of the instances.

Here is my code: DEMO

HTML:

<div class="player" data-track="https://rjmediamusic.com/media/mp3/Masih-Arash-AP-Bia-Bazam.mp3">
<div class="playBtn"></div>
</div>

<div class="player" data-track="https://rjmediamusic.com/media/mp3/Masih-Arash-AP-Hanooz-Hamoonam.mp3">
<div class="playBtn"></div>
</div>


JS:

audio = new Audio();
audio.src= $('.player').data("track");
$(".player").click(function(){
$(".playBtn").toggleClass('active');
if($(".playBtn").hasClass('active')){
audio.play();
}else{
audio.pause();
}
})


When one song is selected to play, no other should play. Is there any solution for this to make it work such that each instance has its own functionality, but all instances share the same Audio object?

Answer

I have made your example with in this jsFiddle: https://jsfiddle.net/mgaskill/zLgpq9dy/

The difficulty is that you are using all instances with the same CSS class, but no IDs. That can work, if you're careful, and that's what I've done. The magic comes from the jQuery $(this) object within an event handler.

Finding the correct play button

var playButton = $(this).find(".playBtn");

Check the play button's class

if (playButton.hasClass('active')) {

Reassigning the audio source

  audio.src= $(this).data("track");

These allow the source to be re-used amongst multiple players.

Here is the updated Javascript:

audio = new Audio();

$(".player").click(function(){
    var playButton = $(this).find(".playBtn");

    if (!playButton.hasClass('current')) {
        $(".playBtn").removeClass("active");
        $(".playBtn").removeClass("current");
        playButton.addClass("current");
        audio.src= $(this).data("track");
    }

    playButton.toggleClass('active');

    if (playButton.hasClass('active')) {
        audio.play();
    } else {
        audio.pause();
    }
});

These changes separate whether a player was actively playing from whether it was the current player, allowing the audio to be resumed from a paused state. When switching from one player to another, all other players are set to not active, allowing the visual state to be properly represented for each player.

The audio source is now assigned to the current player when the player switches. This will stop any previous player from continuing to play, and allow the new player to start when it becomes active.