loru88 loru88 - 2 months ago 35
Javascript Question

close popup after vimeo video finish

I have implemented a little script to close magnific popup when a vimeo video finish using froogaloop,

this is my code:

var SlampLightbox = (function(undefined){

var mp; //store Magnific Popup global object

var mp_exixts = function(){
if( $.fn.magnificPopup ){
mp = $.magnificPopup.instance
return true;
}else{
return false;
}
}

var open_from_hash = function(){
var hash = window.location.hash.slice(1); //cache hash

if( hash.length > 1 && hash != '#!'){
var mark_pos = hash.indexOf('?');
if( mark_pos != -1)
hash = hash.substring(0, mark_pos);

var selector = 'a[name='+hash+']';
$(selector).click(); //trigger click event on the element to open magnificPopup

}
}

var open = function($element){
$element.magnificPopup({
delegate: 'a',
type: 'iframe',
tLoading: '',
iframe: {
markup: '<div class="slamp-mfp-iframe-scaler">'+
'<button title="Close (Esc)" type="button" class="slamp-mfp-close">x</button>'+
'<iframe id="vimeoplayer" class="mfp-iframe" frameborder="0" allowfullscreen></iframe>'+
'</div>', // HTML markup of popup, `mfp-close` will be replaced by the close button
patterns: {
vimeo:{
index: 'vimeo.com/',
id: '/',
src: '//player.vimeo.com/video/%id%?autoplay=1&api=1&player_id=vimeoplayer'
}
}
},
callbacks: {
markupParse: function(template, values, item) {

_attachVideoEvent(template, values, item);


}

}
})
}

var _close = function(){
mp.close();
}

var _attachVideoEvent = function(template, values, item){

var playerOrigin = '*';
var player = $f( template.find("iframe")[0] );

if( player.length == 0 )
return;

var onFinish = function(){
_close();
}

player.addEvent('ready', function() {
player.addEvent('finish', onFinish);
});



}

return {
init: function($element){//input must be a jQuery object

if( mp_exixts() ){
open($element);

if( $element.length == 0)
return;

open_from_hash(); //open a video specified in the hash, if any

$(document.body).on('click', '.slamp-mfp-close', _close);
}else{
console.error("MagnificPopup doesn't exists");
return false;
}

},
mp: mp
}
})(undefined);
window.SlampLightbox = SlampLightbox; //global function


you can view it here:

http://codepen.io/anon/pen/oxZpPL


but it works just once, because the second time I click on the img I get a

javascript error:


VM983 froogaloop2.min.js:1 Uncaught TypeError: Cannot read property
'postMessage' of null


but I can't understand why, it's my fault? o a froogaloop bug?
please help me to understand

thanks

Answer

Try this codepen ;)

Here when we attach _attachVideoEvent it do some postMessage thing which throws an error and JavaScript execution breaks; We have delayed this binding so that pop open and then we do binding thing. It still throw error but no problem.

<div class="video_header">
    <a class="thumb-video" name="video" href="https://vimeo.com/159375756">
    <img class="img-responsive" src="http://test.slamp.it/wp-content/themes/slamp/partials/templates/bob-wilson/img/timeline/Robert-Wilson-project-SlampHQ_thumb.jpg">
    </a>
</div>

/**
*   JS module for open elements in lightbox
*
* @dependencies MagnificPopup
**/
var SlampLightbox = (function(undefined){

    var mp; //store Magnific Popup global object

    var mp_exixts = function(){
        if( $.fn.magnificPopup ){
            mp = $.magnificPopup.instance
            return true;
        }else{
            return false;
        }
    }

    var open_from_hash = function(){
        var hash = window.location.hash.slice(1); //cache hash

        if( hash.length  > 1 && hash != '#!'){
            var mark_pos = hash.indexOf('?');
            if( mark_pos != -1)
                hash = hash.substring(0, mark_pos);

            var selector = 'a[name='+hash+']';
            $(selector).click(); //trigger click event on the element to open magnificPopup

         }
    }

    var open = function($element){
        $element.magnificPopup({
            delegate: 'a',
            type: 'iframe',
            tLoading: '',
            iframe: {
              markup: '<div class="slamp-mfp-iframe-scaler">'+
                        '<button title="Close (Esc)" type="button" class="slamp-mfp-close">x</button>'+
                        '<iframe id="vimeoplayer" class="mfp-iframe" frameborder="0" allowfullscreen></iframe>'+
                      '</div>', // HTML markup of popup, `mfp-close` will be replaced by the close button
     patterns: {
       vimeo:{
          index: 'vimeo.com/',
          id: '/',
          src: '//player.vimeo.com/video/%id%?autoplay=1&api=1&player_id=vimeoplayer'
       }
     }
            },
            callbacks: {
                /*
                beforeOpen: function(){
                    $(window).on("navigate", function (event, data) {
                      var direction = data.state.direction;
                      console.log( direction );
                      if (direction == 'back') {
                        $.magnificPopup.close();
                      }
                    });

                },
      */
                markupParse: function(template, values, item) {
        setTimeout(function(){
          _attachVideoEvent(template, values, item);  
        });
                },
                elementParse: function(item){
                    var $item = item.el; //opened jQuery object

                    if( $item.hasClass("video-thumb") ){ //google analytics track event
                        var video_name = $item.attr("name");

                        if(history.pushState)
                            history.pushState(null, null, '#'+video_name);
                        else
                            location.replace(('' + window.location).split('#')[0] +'#'+video_name);

                        if( typeof ga != 'undefined' )
                            ga('send','event', 'Lightbox open', 'Video page', video_name);

                    }
                },
                close: function(){
                    if( window.location.hash != '' ){
                        if(history.pushState)
                            history.pushState(null, null, '#!');
                        else
                            location.replace(('' + window.location).split('#')[0] +'#!');
                    }
                }

            }
        })
    }

    var _close = function(){
        mp.close();
    }

var _attachVideoEvent = function(template, values, item){

    var playerOrigin = '*';
    var player = $f( template.find("iframe")[0] );

    if( player.length == 0 )
    return;

    var onFinish = function(){
        _close();
    }

    player.addEvent('ready', function() {
        player.addEvent('finish', onFinish);
    });
  }

    return {
        init: function($element){//input must be a jQuery object

            if( mp_exixts() ){
                open($element);

                if( $element.length == 0)
                    return;

                open_from_hash(); //open a video specified in the hash, if any

                $(document.body).on('click', '.slamp-mfp-close', _close);
            }else{
                console.error("MagnificPopup doesn't exists");
                return false;
            }

            },
        mp: mp
    }
})(undefined);
window.SlampLightbox = SlampLightbox; //global function


$(document).ready(function() {
    SlampLightbox.init( $('.video_header') );
});