Javascript Youtube iframe api 未在 YouTubeIframeAPIReady 上触发
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12256382/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Youtube iframe api not triggering onYouTubeIframeAPIReady
提问by jribeiro
I've been battling with the youtube iframe api for quite some time now. Somehow the method onYouTubeIframeAPIReady
is not always triggered.
一段时间以来,我一直在与 youtube iframe api 作斗争。不知何故,该方法onYouTubeIframeAPIReady
并不总是被触发。
From the symptoms it seems a loading problem. No errors are shown in the inspector.
从症状来看,似乎是加载问题。检查器中未显示任何错误。
Here is my code:
这是我的代码:
HTML
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
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.
问题是有时什么都不会被打印出来,console.log
也没有任何反应。
On mobile phones this happens all the time. Any ideas?
在手机上,这种情况一直发生。有任何想法吗?
回答by bcm
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.
确保您的onYouTubeIframeAPIReady
函数在全局级别可用,而不是嵌套(隐藏)在另一个函数中。
回答by Erick R Soto
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 对象以确保它被全局调用。如果您的代码使用 amd,这将很有帮助。
window.onYouTubeIframeAPIReady = function() {}
回答by Peng? Dzsó
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):
在这种情况下,请确保在声明之后将特定脚本插入到 dom(insertBefore()
在您的情况下,现在调用全局范围内的内容):
回答by Joar
If you load the IFrame Player API code asynchronously as follows:
如果您按如下方式异步加载 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>
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).
那么该函数onYouTubeIframeAPIReady
将不会被调用,因为相同的代码被加载了两次(当 api 完全加载时,该函数只被调用一次)。
So use just one of the ways according to your needs.
因此,请根据您的需要使用其中一种方法。
回答by Joao
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:
在重新审视这个之后,我在使用 webpack(或者我假设任何其他 commongJS 模块系统)时找到了一个适合我的解决方案,或者如果你发现 youtube api 在你自己的 JS 文件之前准备好了,是使用间隔 - 直到 youtube 提供一些承诺回调的形式:
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.
就我而言,这似乎是最能防错的。
回答by Ben Wheeler
Make sure you are testing the page by having it actually served on the web, not just loaded locally. YouTube iFrame API behavior is inconsistent/nondeterministic
确保您通过实际在网络上提供页面来测试页面,而不仅仅是在本地加载。YouTube iFrame API 行为不一致/不确定
回答by Diogo Garcia
I had a similar problem, In my case onYouTubeIframeAPIReady was being called so fast that the actual implementation wasn't ready for the right call. So after youtube player_api call I added a simple implementation with a var for verification of onYouTubeIframeAPIReady just like that:
我有一个类似的问题,在我的例子中 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>
回答by Matt Loye
I actually made this to lazy load the youtube player. Seems bullet proof to me.
我实际上这样做是为了延迟加载 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);
}
回答by nosforz
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 在页面加载时完成这项工作。我知道这并不理想,但这只是大多数情况下解决问题的另一项检查。
setTimeout(function(){
if (typeof(player) == 'undefined'){
onYouTubeIframeAPIReady();
}
}, 3000)