javascriptjquerymagnific-popupvimeo-apifroogaloop

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


Solution

  • 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.

    /**
     *	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'));
    });
    <link href="https://cdnjs.cloudflare.com/ajax/libs/magnific-popup.js/1.1.0/magnific-popup.min.css" rel="stylesheet"/>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/magnific-popup.js/1.1.0/jquery.magnific-popup.min.js"></script>
    <script src="https://f.vimeocdn.com/js/froogaloop2.min.js"></script>
    
    <div class="video_header">
      <a class="thumb-video" name="video" href="https://vimeo.com/159375756">
        <img class="img-responsive" height="250" src="http://test.slamp.it/wp-content/themes/slamp/partials/templates/bob-wilson/img/timeline/Robert-Wilson-project-SlampHQ_thumb.jpg">
      </a>
    </div>