Youtube iframe api未在YouTubeIframeAPIReady上触发



我已经与youtube iframe api斗争了很长一段时间。不知怎的,方法onYouTubeIframeAPIReady并不总是被触发的。

从症状来看,这似乎是一个负载问题。检查员中未显示任何错误。

这是我的代码:

HTML

<div id="player"></div>
          <script>
            videoId = 'someVideoId';
            var tag = document.createElement('script');
            tag.src = "//www.youtube.com/iframe_api";
            var firstScriptTag = document.getElementsByTagName('script')[0];
            firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
          </script>

JS

(在页面末尾调用。我试图将代码放在上面的脚本后面,结果是一样的。)

var isReady = false
  , player
  , poster
  , video;
$(function () {
$('.js-play').click(function (e) {
    e.preventDefault();
    interval = setInterval(videoLoaded, 100);
  });
});
function onYouTubeIframeAPIReady() {
  console.log(videoId)
  player = new YT.Player('player', {
    height: '445',
    width: '810',
    videoId: videoId,
    events: {
      'onReady': onPlayerReady//,
      //'onStateChange': onPlayerStateChange
    }
  });
}
function onPlayerReady(event) {
  isReady = true;
  console.log("youtube says play")
}
function videoLoaded (){
  if (isReady) {
      console.log("ready and play")
      poster.hide();
      video.show();
      $('body').trigger('fluidvideos');
      player.playVideo();
      clearInterval(interval);
  } 
}

问题是,有时console.log不会打印任何内容,也不会发生任何事情。

在手机上,这种情况经常发生。有什么想法吗?

这不是超时问题,您不需要手动启动此函数。

确保您的onYouTubeIframeAPIReady函数在全局级别可用,而不是嵌套(隐藏)在另一个函数中。

您可以始终将它附加到窗口对象,以确保它被全局调用。如果您的代码使用amd,这将非常有用。

window.onYouTubeIframeAPIReady = function() {}

如果必须插入函数内部,一种可能的解决方案是而不是:

function onYouTubeIframeAPIReady() {
  // func body...
}

你可以这样申报:

window.onYouTubeIframeAPIReady = function() {
  // func body...
}

在这种情况下,请确保在声明之后向dom插入特定的脚本(在您的情况下,insertBefore()调用全局范围内的内容):

如果异步加载IFrame Player API代码,如下所示:

<script>
var tag = document.createElement('script');
tag.src = "//www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
</script>

您还加载了如下脚本代码:

<script src="http://www.youtube.com/player_api"></script>

则函数CCD_ 5将不会被调用,因为同一代码被加载两次(当api被完全加载时,函数仅被调用一次)。

因此,根据您的需要,只使用其中一种方法。

在重新审视这一点后,我发现了一个适用于我的解决方案,当我使用webpack(或者我假设任何其他常见的JS模块系统)时,或者如果你发现youtube api在你自己的JS文件之前就准备好了,那就是使用间隔-直到youtube提供某种形式的promise回调:

var checkYT = setInterval(function () {
    if(YT.loaded){
        //...setup video here using YT.Player()
        clearInterval(checkYT);
    }
}, 100);

这似乎是我案例中最能证明错误的。

确保您在测试页面时将其实际提供到web上,而不仅仅是本地加载。YouTube iFrame API行为不一致/不确定

我这样做实际上是为了延迟加载youtube播放器。对我来说似乎是防弹的。

window.videoApiLoaded = [];
window.videoApiLoaded.youtube = false;
function loadYoutubeVideo(videoId) {
    window.onYouTubeIframeAPIReady = function() { document.dispatchEvent(new CustomEvent('onYouTubeIframeAPIReady', {})) };
    if(window.videoApiLoaded.youtube == false) {
        var tag = document.createElement('script');
        tag.src = "https://www.youtube.com/iframe_api";
        var firstScriptTag = document.getElementsByTagName('script')[0];
        firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
        window.videoApiLoaded.youtube = true;
    }
    var player;
    document.addEventListener('onYouTubeIframeAPIReady', function (e) {
        player = new YT.Player('player', {
          height: '400',
          width: '600',
          videoId: videoId,
          events: {
            'onStateChange': onYtStateChange
          }
        });
    }, false);
}

我也遇到了类似的问题,在我的案例中,onYouTubeIframeAPIReady被调用得太快,以至于实际实现还没有准备好进行正确的调用。因此,在youtube player_api调用之后,我添加了一个简单的实现,其中包含一个var,用于验证onYouTubeIframeAPIReady,就像这样:

<script src="http://www.youtube.com/player_api"></script>
<script>
var playerReady = false
window.onYouTubeIframeAPIReady = function() { //simple implementation
    playerReady = true;
}
</script>
</header>
.
.
.
<body>
<script>
window.onYouTubeIframeAPIReady = function() { //real and fully implemented
    var player; // ... and so on ...
}
if(playerReady) { onYouTubeIframeAPIReady(); console.log("force to call again") }
</script>

我能够在几乎所有情况下使用页面加载时的简单setTimeout来实现这一点。我知道这并不理想,但这只是在大多数情况下解决问题的另一种检查。

setTimeout(function(){
    if (typeof(player) == 'undefined'){
        onYouTubeIframeAPIReady();
    }
}, 3000)

相关内容

  • 没有找到相关文章

最新更新