Dan JF
Dan JF

Reputation: 55

How to have multiple instances of a jQuery plugin

I am trying to create a SoundCloud music player. It can play any track from SoundCloud, but this plugin is only working if there is only one instance of it in the page. So it wont work if two of the same plugin are in the page.

Here is an example of having two players in the page: JSFiddle

var trackURL = $(".player").text();
$(".player").empty();
$(".player").append("<div class='playBTN'>Play</div>");
$(".player").append("<div class='title'></div>");

var trackId;
SC.get('/resolve', { url: trackURL }, function (track) {
    var trackId = track.id;
    //var trackTitle = track.title;
    $(".title").text(track.title);

    $(".playBTN").on('click tap', function () {
        //trackId = $(".DSPlayer").attr('id');
        stream(trackId);
    });

    // first do async action
    SC.stream("/tracks/" + trackId, {
        useHTML5Audio: true,
        preferFlash: false
    }, function (goz) {
        soundToPlay = goz;
        sound = soundToPlay;
        scTrack = sound;
        //updater = setInterval( updatePosition, 100);
    });
});
var is_playing = false,
    sound;

function stream(trackId) {
    scTrack = sound;
    if (sound) {
        if (is_playing) {
            sound.pause();
            is_playing = false;
            $(".playBTN").text("Play");
        } else {
            sound.play();
            is_playing = true;
            $(".playBTN").text("Pause");
        }
    } else {
        is_playing = true;
    }
}

If you remove any of these div elements that hold the .player class, the other element will work. So it only doesn't work because there are two instances of the same plugin.

How can I fix it? to have multiple instances of the player in one page?

Upvotes: 3

Views: 246

Answers (1)

ZaxLofful
ZaxLofful

Reputation: 1147

I have identified the problem. It has to do with the fact that you are trying to load multiple tracks at the same time, but have not separated the code to do so.

As @Greener mentioned you need to iterate over the .player instances separately and execute a SC.get() for each one of them.

Here is what I see happening that is causing the problem:

var trackURL = $(".player").text();

^The code above returns a string that contains both of the URLs you want to use back-to-back without spaces. This creates a problem down the road because of this code:

SC.get('/resolve', { url: trackURL }, function (track) {...

That is a function that is trying to load the relevant song from SoundCloud. You are passing it a variable "trackURL" for it to try and load a specific URL. The function gets a string that looks like "URLURL" what it needs is just "URL".

What you can do is iterate over all the different ".player" elements that exist and then call the sounds that way. I modified your script a little to make it work using a for loop. I had to move the "empty()" functions into the for loop to make it work correctly. You have to use .eq(index) when referring to JQuery array of elements.

Like this:

var trackURL
var trackId;

for(index = 0; index < $(".player").length; index++){
    trackURL = $(".player").eq(index).text();
    //alert(trackURL);
    $(".player").eq(index).empty();
    $(".player").eq(index).append("<div class='playBTN'>Play</div>");
    $(".player").eq(index).append("<div class='title'></div>");
    SC.get('/resolve', { url: trackURL }, function (track) {
    var trackId = track.id;
    alert(track.id);
    //var trackTitle = track.title;
    $(".title").eq(index).text(track.title);

    $(".playBTN").eq(index).on('click tap', function () {
        //trackId = $(".DSPlayer").attr('id');
        stream(trackId);
    });

    // first do async action
    SC.stream("/tracks/" + trackId, {
        useHTML5Audio: true,
        preferFlash: false
    }, function (goz) {
        soundToPlay = goz;
        sound = soundToPlay;
        scTrack = sound;
        //updater = setInterval( updatePosition, 100);
    });
});
}

This is not a completely finished code here, but it will initiate two separate songs "ready" for streaming. I checked using the commented out alert what IDs SoundCloud was giving us (which shows that its loaded now). You are doing some interesting stuff with your streaming function and with the play and pause. This should give you a good idea on what was happening and you can implement your custom code that way.

Upvotes: 2

Related Questions