0

Note: This is a knowledge-sharing question because I've already found a nice solution.

The problem:

The playlist implementation (http://jplayer.org/latest/demo-02-jPlayerPlaylist/) was built by utilising the jPlayer events. One of the side effects of this is that if you want to respond to track start by binding to 'setmedia', and track end by binding to the 'ended' event, you will find that 'ended' is triggered only after the next line was activated.

This means that the events will fire in this order:

  • setmedia of track #1
  • setmedia of track #2 (including moving the jp-playlist-current class)
  • ended of track #1

So the question is: how to get the 'ended' event be fired before moving to the next track?

ishahak
  • 6,585
  • 5
  • 38
  • 56

1 Answers1

0

The root cause of this problem is that the playlist implementation binds itself to the 'ended' event before our binding.

So the solution will be to bind our code before the code of the playlist.

In the following answer: jQuery bind event listener before another we can find the following implementation for preBind method:

$.fn.preBind = function (type, data, fn) {
    this.each(function () {
        var $this = $(this);

        $this.bind(type, data, fn);

        var currentBindings = $._data(this, 'events')[type];
        if ($.isArray(currentBindings)) {
            currentBindings.unshift(currentBindings.pop());
        }
    });
    return this;
};  

After adding this preBind, we can do the following within the jPlayer 'ready' handler:

$("#jquery_jplayer_1")
    .preBind($.jPlayer.event.ended, function(e) { 
        var cur = $('.jp-playlist').find('li.jp-playlist-current'),
            ix = cur.index(),
            is_last = cur.next().get().length == 0;
        console.log('ended index=' + ix + ', is_last=' + is_last);
    });   
ishahak
  • 6,585
  • 5
  • 38
  • 56