【问题标题】:Youtube iframe api not triggering onYouTubeIframeAPIReadyYoutube iframe api 未触发 onYouTubeIframeAPIReady
【发布时间】:2012-08-28 16:39:16
【问题描述】:

我已经与 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 没有打印任何内容,也没有任何反应。

在手机上,这种情况一直都在发生。有什么想法吗?

【问题讨论】:

标签: javascript jquery iframe youtube youtube-api


【解决方案1】:

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

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

【讨论】:

  • 这是正确的解决方案,到目前为止。我遇到了同样的问题,但我的函数在 $(document).ready() 中。我把它移了出来,它起作用了。
  • 难道没有我们可以监听的自定义事件,而不是让函数在全局范围内可用吗?这感觉真的很脏!类似$('document').on('youTubeIframeAPIReady', function(e){});...
  • @AugustinRiedinger 你找到合适的活动了吗?
  • 暂时没有。也许是自定义脚本:window.onYouTubeIframeAPIReady = function() { document.dispatchEvent(new CustomEvent('onYouTubeIframeAPIReady', {})) })
【解决方案2】:

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

window.onYouTubeIframeAPIReady = function() {}

【讨论】:

  • 我知道这是一个旧线程。对于使用 requireJS 的其他任何人,此解决方案可以解决此问题。
  • 帮助我使用 Meteor 和 YouTube Iframe API 包。
  • 此答案为我解决了仅在 Safari 中未调用 onYouTubeIframeAPIReady 函数的问题。该函数已经在全局范围内,并且在 Firefox 和 Chrome 中运行良好。将其附加到窗口修复了 Safari 中的问题。
【解决方案3】:

如果你必须把一个函数放在里面,一个可能的解决方案是 而不是:

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

你可以这样声明:

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

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

【讨论】:

    【解决方案4】:

    如果您按如下方式异步加载 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完全加载时调用一次)。

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

    【讨论】:

      【解决方案5】:

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

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

      在我的情况下,这似乎是最防错的。

      【讨论】:

        【解决方案6】:

        确保您通过实际在网络上提供页面来测试页面,而不仅仅是在本地加载。 YouTube iFrame API behavior is inconsistent/nondeterministic

        【讨论】:

        • 天哪...非常感谢您指出这一点。无法弄清楚为什么它不起作用。
        【解决方案7】:

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

        【讨论】:

          【解决方案8】:

          我遇到了类似的问题,在我的例子中,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>
          

          【讨论】:

            【解决方案9】:

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

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

            【讨论】:

            • 这在各个层面都是错误的。即使我们正在等待玩家准备好,您也可以使用 setInterval。
            • 投了反对票,因为这不是正确的解决方案。 bcm 的解决方案是正确的方法。 ...'确保您的 onYouTubeIframeAPIReady 函数在全局级别可用,而不是嵌套(隐藏)在另一个函数中。'
            猜你喜欢
            • 2012-11-18
            • 2014-05-24
            • 2013-06-09
            • 2014-09-22
            • 2015-01-28
            • 1970-01-01
            • 2022-01-24
            • 1970-01-01
            相关资源
            最近更新 更多