Youtube iframe api not triggering onYouTubeIframeA

2019-01-07 13:06发布

I've been battling with the youtube iframe api for quite some time now. Somehow the method onYouTubeIframeAPIReady is not always triggered.

From the symptoms it seems a loading problem. No errors are shown in the inspector.

Here is my code:

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

(called at the end of the page. I tried to place the code right after the above script and the result was the same.)

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);
  } 
}

The problem is that sometimes nothing gets printed by the console.log and nothing happens.

On mobile phones this happens all the time. Any ideas?

9条回答
家丑人穷心不美
2楼-- · 2019-01-07 13:59

If you have to put in inside to a function, one possible solution is instead of:

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

you can declare it like this:

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

In this case make sure, that you insert the certain script to the dom after the declaration (the insertBefore() call what is in the global scope now in your case):

查看更多
Explosion°爆炸
3楼-- · 2019-01-07 13:59

After revisiting this, I found a working solution for me when using webpack (or I assume any other commongJS module system), or if you find the youtube api is ready before your own JS file, was to use an interval - until youtube provides some form of promise callback:

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

        clearInterval(checkYT);
    }
}, 100);

This seemed to be the most error-proof in my case.

查看更多
该账号已被封号
4楼-- · 2019-01-07 13:59

I was able to make this work under almost all circumstances with a simple setTimeout on load of the page. Not ideal, I know, but it is just another check that fixes the problem most of the time.

setTimeout(function(){
    if (typeof(player) == 'undefined'){
        onYouTubeIframeAPIReady();
    }
}, 3000)
查看更多
登录 后发表回答