41

我已经与 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,什么也没有发生。

在手机上,这种情况一直在发生。有任何想法吗?

4

9 回答 9

73

这不是超时问题,您不需要手动触发此功能。

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

于 2013-03-13T01:05:57.620 回答
53

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

window.onYouTubeIframeAPIReady = function() {}
于 2013-05-22T20:50:47.670 回答
14

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

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

你可以这样声明:

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

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

于 2013-10-01T13:46:30.430 回答
9

如果您按如下方式异步加载 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>

那么函数onYouTubeIframeAPIReady将不会被调用,因为相同的代码被加载了两次(当 api 完全加载时,函数只被调用一次)。

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

于 2013-08-13T06:29:47.873 回答
7

重新审视这个之后,我在使用 webpack (或者我假设任何其他 commongJS 模块系统)时为我找到了一个可行的解决方案,或者如果你发现 youtube api 在你自己的 JS 文件之前准备好,则使用间隔 - 直到 youtube 提供一些承诺回调的形式:

var checkYT = setInterval(function () {
    if(YT.loaded){
        //...setup video here using YT.Player()

        clearInterval(checkYT);
    }
}, 100);

就我而言,这似乎是最防错的。

于 2016-03-16T22:52:50.033 回答
3

确保您通过在网络上实际提供页面来测试页面,而不仅仅是在本地加载。YouTube iFrame API 行为不一致/不确定

于 2013-11-01T17:52:33.643 回答
1

实际上,我这样做是为了延迟加载 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);

}
于 2017-04-26T14:18:52.177 回答
0

我遇到了类似的问题,在我的情况下,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>
于 2015-12-21T16:02:51.300 回答
-7

在几乎所有情况下,我都能在页面加载时使用简单的 setTimeout 来完成这项工作。不理想,我知道,但这只是大多数时候解决问题的另一种检查。

setTimeout(function(){
    if (typeof(player) == 'undefined'){
        onYouTubeIframeAPIReady();
    }
}, 3000)
于 2013-02-07T04:01:46.483 回答