YouTube API - Firefox/IE为任何"播放器"返回错误"X不是函数".请求

rel*_*lic 2 html javascript jquery scope youtube-api

我一直在试图让一个相当简单的YouTube api集成在FF/IE中工作并且到目前为止没有运气.

这听起来像是一个范围问题或者在玩家初始化之前进行的调用,但我尝试过的一切都表明它不是这两件事之一.另外值得注意的是,一切都在(仅)Chrome中完美运行.

// Async api load per YT documentation...
var tag = document.createElement('script');
tag.src = "//www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

// Declare player and set basic functions...
var player

playVideo = function() { player.playVideo(); }
stopVideo = function() { player.stopVideo(); }

// YT Api ready function...
function onYouTubeIframeAPIReady() {
  player = new YT.Player('player', {
    videoId: "TkJcg4bmAYs",
    events: {
      'onStateChange': onPlayerStateChange
    }
  });

  // After player object created, bind popup function to page anchors...
  var popup = $('#video-popup')
  ,   popupFrame = $(popup).children('.center')
  ;

  $('a[data-vid]').click(function(e){
    e.preventDefault ? e.preventDefault() : e.returnValue = false;

    var clicked = $(e.target).closest('a')
    ,   videoID = $(clicked).attr('data-vid')
    ;

    if (!$(popup).hasClass('working')){
      // If popup isn't already working, cue video and animate popup in... 
      player.cueVideoById({videoId:videoID});

      $(popup).addClass('working');
      $(popup).css('display','block').animate({
        opacity: '1'
      }, 200, function(){
        playVideo();
        $(popup).removeClass('working');
      });
    }
  });
}
Run Code Online (Sandbox Code Playgroud)

使用api和弹出代码链接到测试页面,在Chrome中工作,但在其他浏览器中无法使用. http://www.crackin.com/dev/regions/pathBuild/

rel*_*lic 9

将一半的键盘键嵌入我的额头之后,我终于偶然发现了问题的令人沮丧的简单根源......这只是一个可见性问题!ARRGG!显然,FireFox和IE在设置为display:none;时初始化时无法访问播放器对象,但Chrome足够智能,即使隐藏也仍然可以初始化并定位它.

在我的特定情况下,修复程序是将弹出窗口加载为display:block with opacity:0,THEN初始化api,然后将弹出窗口设置为在YT api init函数内显示:none.像这样的东西:

首先,CSS ......

#video-popup { display: block; opacity: 0; }
Run Code Online (Sandbox Code Playgroud)

..然后javascript ...

var player
,   popup = $('#video-popup')
;

function onYouTubeIframeAPIReady() {
    player = new YT.Player('player', {
        videoId: "TkJcg4bmAYs"
    });
    $(popup).css('display','none');
}
Run Code Online (Sandbox Code Playgroud)

现在我需要喝醉了.


附加功能:在最终找出问题的根源后,我能够隔离一些额外的IE浏览器问题并找出解决方案.这些只是为了防止其他人遇到类似的问题,他们也许能够从中开辟出自己的解决方案.我的解决方案可能有点特定情况,但如果有人在弹出窗口中放置youtube视频并需要IE支持,这可能会有所帮助.

上面的修复(在YT就绪功能中设置显示:无)似乎对IE8不起作用,但是通过将其包装在短暂的超时中快速修复:

function onYouTubeIframeAPIReady() {
    player = new YT.Player('player', {
        videoId: "TkJcg4bmAYs"
    });
    setTimeout(function(){
        $(popup).css('display','none');
    }, 500);
}
Run Code Online (Sandbox Code Playgroud)

IE7有点棘手,因为看起来如果播放器是使用display:none隐藏的,它会立即变得不可用,无论它是否已被初始化.

使用条件注释将类应用于标记,您可以添加一些IE特定的css以使弹出窗口"可见"但是将其隐藏在屏幕外.

#video-popup { position: fixed; top: 0; left: 0; width: 100%; height: 100%; display: none; opacity: 0; }
.ie7Detect #video-popup { display: block; left: -101% }
#video-popup.open { left:0 !important; }
Run Code Online (Sandbox Code Playgroud)

还有一个问题是,在IE7和8中,即使父容器设置为不透明度0(在页面仍在加载时发生),youtube播放器仍然可见.我尝试添加规则以进一步定位弹出窗口的内容并设置它们的不透明度,但是不起作用并且也不是超级干净.我解决的是使用加载类.

所以弹出窗口有一个加载类:

<div id="video-popup" class="loading">
    <!-- bunch of stuff in here -->
</div>
Run Code Online (Sandbox Code Playgroud)

功能更新......

function onYouTubeIframeAPIReady() {
    player = new YT.Player('player', {
        videoId: "TkJcg4bmAYs",
    });
    setTimeout(function(){
        $(popup).removeClass('loading');
    }, 500);
}
Run Code Online (Sandbox Code Playgroud)

CSS看起来像这样......

#video-popup { position: fixed; top: 0; left: 0; width: 100%; height: 100%; display: none; opacity: 0; }
.ie7Detect #video-popup, #video-popup.loading { display: block; left: -100% }
#video-popup.open { left:0 !important; }
Run Code Online (Sandbox Code Playgroud)

拼图的最后一部分是在弹出函数实际上是可见的时候为你的弹出函数添加一个类名"open".

希望有助于某人避免将来出现一些潜在的麻烦.不利的一面是,在解决这些问题之后你可能不会像喝酒一样热心,因为你可能会这样.

和平,哟.