简体   繁体   English

如何拥有jQuery插件的多个实例

[英]How to have multiple instances of a jQuery plugin

I am trying to create a SoundCloud music player. 我正在尝试创建一个SoundCloud音乐播放器。 It can play any track from SoundCloud, but this plugin is only working if there is only one instance of it in the page. 它可以播放来自SoundCloud的任何曲目,但只有在页面中只有一个实例时,此插件才有效。 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 这是一个在页面中有两个玩家的例子: 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. 如果删除任何包含.player类的div元素,则另一个元素将起作用。 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? 在一个页面中有多个播放器实例?

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. 正如@Greener所提到的,你需要分别迭代.player实例并为它们中的每一个执行SC.get()。

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. ^上面的代码返回一个字符串,其中包含您想要背靠背使用的两个不带空格的URL。 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. 这是一个试图从SoundCloud加载相关歌曲的功能。 You are passing it a variable "trackURL" for it to try and load a specific URL. 您正在向它传递一个变量“trackURL”,以便尝试加载特定的URL。 The function gets a string that looks like "URLURL" what it needs is just "URL". 该函数获取一个看起来像“URLURL”的字符串,它只需要“URL”。

What you can do is iterate over all the different ".player" elements that exist and then call the sounds that way. 你可以做的是迭代存在的所有不同的“.player”元素,然后以这种方式调用声音。 I modified your script a little to make it work using a for loop. 我稍微修改了你的脚本,使其使用for循环工作。 I had to move the "empty()" functions into the for loop to make it work correctly. 我不得不将“empty()”函数移动到for循环中以使其正常工作。 You have to use .eq(index) when referring to JQuery array of elements. 在引用JQuery元素数组时,必须使用.eq(index)。

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). 我使用已注释的警报检查了SoundCloud给我们的ID(显示它现在已加载)。 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. 这应该可以让您了解正在发生的事情,并且可以通过这种方式实现自定义代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM