Youtube iframe api not triggering onYouTubeIframeAPIReady
Solution 1
It is not a timeout issue, and you should not need to fire this function manually.
Make sure your onYouTubeIframeAPIReady
function is available at the global level, not nested (hidden away) within another function.
Solution 2
You can always append it to the window object to make sure it is evoked globally. This is helpful if your code is using amd.
window.onYouTubeIframeAPIReady = function() {}
Solution 3
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):
Solution 4
If you load the IFrame Player API code asynchronously as follows:
<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>
and you are also loading the script code like this:
<script src="http://www.youtube.com/player_api"></script>
then the function onYouTubeIframeAPIReady
won't be called due to the same code is being loaded twice (the function is called just one time when the api is completely loaded).
So use just one of the ways according to your needs.
Solution 5
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.
jribeiro
Full Stack Web Developer driven by passion, innovation and creativity! I specialise in creating great web and mobile experiences for companies and creatives
Updated on July 09, 2022Comments
-
jribeiro almost 2 years
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?
-
Don Boots about 11 yearsThis is wrong on every level. Even if we were waiting for the player to be ready, you would use setInterval.
-
Don Boots about 11 yearsThis is the correct solution, BY FAR. I had the same problem, but my function was in $(document).ready(). I moved it out and it worked.
-
r8n5n about 11 yearsVoted down as this is not the correct solution. bcm's solution is the correct way to do this. ... 'Make sure your onYouTubeIframeAPIReady function is available at the global level, not nested (hidden away) within another function.'
-
DavidT over 9 yearsI know this is an old thread. For anyone else using requireJS this solution fixes the issue.
-
Augustin Riedinger about 9 yearsAin't there a custom event we could listen to instead of making the function available in the global scope? This feels really dirty! Something like
$('document').on('youTubeIframeAPIReady', function(e){});
... -
Joel Balmer over 8 yearsOh my god... Thank you SO much for pointing this out. Couldn't figure out why it wasn't working.
-
Ben Swinburne almost 8 years@AugustinRiedinger did you find a suitable event to listen for?
-
Kodie Grantham over 7 yearsHelped me with Meteor and the YouTube Iframe API package as well.
-
Augustin Riedinger over 7 yearsNot for now. Maybe a custom script:
window.onYouTubeIframeAPIReady = function() { document.dispatchEvent(new CustomEvent('onYouTubeIframeAPIReady', {})) })
-
Yabsley almost 6 yearsThis answer fixed an issue for me with the onYouTubeIframeAPIReady function not being called on in Safari only. The function was already in the global scope and was working fine in Firefox and Chrome. Appending it to window fixed the issue in Safari.
-
GAV almost 2 yearsNice, Solved my issue when compiling in Yarn encore