Youtube iframe api没有触发YouYouTubeIframeAPIReady

jri*_*iro 37 javascript youtube iframe jquery youtube-api

我已经与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>
Run Code Online (Sandbox Code Playgroud)

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);
  } 
}
Run Code Online (Sandbox Code Playgroud)

问题是,有时没有任何东西被打印出来console.log,没有任何反应.

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

bcm*_*bcm 68

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

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

  • 是不是我们可以听取自定义事件而不是在全局范围内使用该功能?这感觉很脏!像`$('document').on('youTubeIframeAPIReady',function(e){});`... (3认同)
  • 现在不行。也许是一个自定义脚本:`window.onYouTubeIframeAPIReady = function(){document.dispatchEvent(new CustomEvent('onYouTubeIframeAPIReady',{}))})` (2认同)

小智 46

您始终可以将其附加到窗口对象,以确保它是全局引发的.如果您的代码使用amd,这将非常有用.

window.onYouTubeIframeAPIReady = function() {}
Run Code Online (Sandbox Code Playgroud)

  • 还是webpack (2认同)

Pen*_*zsó 11

如果你必须在函数内部放入一个可能的解决方案而不是:

function onYouTubeIframeAPIReady() {
  // func body...
}
Run Code Online (Sandbox Code Playgroud)

你可以像这样声明:

window.onYouTubeIframeAPIReady = function() {
  // func body...
}
Run Code Online (Sandbox Code Playgroud)

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


Joa*_*oar 8

如果以异步方式加载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>
Run Code Online (Sandbox Code Playgroud)

你也加载这样的脚本代码:

<script src="http://www.youtube.com/player_api"></script>
Run Code Online (Sandbox Code Playgroud)

然后onYouTubeIframeAPIReady由于相同的代码被加载两次而不会调用该函数(该函数在api完全加载时被调用一次).

因此,请根据您的需求使用其中一种方式.


Joa*_*oao 7

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

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

        clearInterval(checkYT);
    }
}, 100);
Run Code Online (Sandbox Code Playgroud)

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