Search code examples
javascriptjqueryvimeo

How can I check if all vimeo videos on page were played on click of a button?


(using https://github.com/vimeo/player.js/)

I have 4 Vimeo embedded videos on a page and a button (next) to move to the next page. I would like to allow the user to move to the next page only after they have viewed all 4 videos.

I start by collecting all videos: var iframes = $( 'iframe.video' );

Then I loop through them to use the vimeo api and check if they were played:

var videos = [];
var videos_flags = [];
for( var i = 0 ; i < iframes.length ; i++ ) {
    videos[i] = new Vimeo.Player( iframes[i] );
    videos[i].on('play', function( data ) {
        videos_flags[i] = true;
    } );
}

Eventually, if I do console.log( videos_flags ) I get 3 empty and 1 true no matter how many videos I have played.

$( '.next' ).on( 'click', function() {
    console.log( videos_flags );
} );

What am I doing wrong?

Thanks!


Solution

  • Its about closures, you need to bind the variable to your elements.

    function bindValue (n, videos) {
        return function() {
            console.log(n)
            videos_flags[n] = true;
        }
    }
    
    for( var i = 0 ; i < iframes.length ; i++ ) {
        videos[i] = new Vimeo.Player( iframes[i], options );
        videos[i].on('play',  bindValue(i, videos_flags));
    }
    

    A working example here. (added options when creating video player just to avoid the extra attributes data-vimeo-id or data-vimeo-url needed by the player, you should not need those)

    An even better solution with let (the i variable is all you need to change):

    for( let i = 0 ; i < iframes.length ; i++ ) {
        videos[i] = new Vimeo.Player( iframes[i], options );
        videos[i].on('play', function( data ) {
            alert(i)
            videos_flags[i] = true;
        } );
    }
    

    Example here.

    A better explanaition of why here.