我们有一个包含YouTube视频的Facebook Tab应用程序(可能无关)。
第一次使用该页面从空的缓存加载。但是,在随后的页面加载中,一旦视频停止加载,onStateChange
处理程序根本不会在Internet Explorer中启动。
在Chrome和Firefox中一切正常,此问题似乎只会影响IE,而且奇怪的是,仅来自非空的缓存。它看起来与gdata-issues#2942非常相似,除了该问题具有Status: Fixed
。
我们代码的相关块如下:
页
<!DOCTYPE html>
...
<div class="player-surround">
<div id="ytplayer">
You need Flash player 9+ and JavaScript enabled to view this video.
</div>
</div>
...
<script src="//ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js"></script>
<script type="text/javascript">
var params = { allowScriptAccess: "always" };
var atts = { id: "ytplayer" };
// YouTube video ID redacted here
swfobject.embedSWF("http://www.youtube.com/v/XXXXXXXXXXXXXX?enablejsapi=1&playerapiid=ytplayer&version=3",
"ytplayer", "587", "330", "8", null, null, params, atts);
</script>
<script src="//www.youtube.com/player_api"></script>
包括javascript
MFA.onPlayerStateChange = function(evt) {
var state = this.getPlayerState();
log('158: STATE CHANGED: ' + state);
// Then do some stuff, but the `log` call above doesn't fire
}
MFA.getPlayerState = function() {
var playerState;
if (this.ytplayer) {
playerState = this.ytplayer.getPlayerState();
switch (playerState) {
case 5: return 'video cued';
case 3: return 'buffering';
case 2: return 'paused';
case 1: return 'playing';
case 0: return 'ended';
case -1: return 'unstarted';
default: return 'Status uncertain';
}
}
};
(显然,我错过了这个问题中的一堆无关代码。)
除非IE以前看过页面,否则有人有任何想法,为什么一切都可以正常工作?我可以理解它是否从未在IE中工作,但是当缓存为空时,它可以正常工作,但是当您重新加载页面时会失败。
所有的想法都非常感激。
编辑
Greg Schechter指出,我的代码示例使用swfobject.embedSWF
代码,而不是嵌入式代码。
我们最初确实使用了iFrame嵌入式代码:
var s = {
playerHeight: '330',
playerWidth: '587',
playerVars: { 'rel': 0 },
videos: {
stage1: 'XXXXXXXXXXXXXX', // ...
}
};
window.onYouTubePlayerAPIReady = function() {
MFA.ytplayer = new YT.Player('ytplayer', {
height: s.playerHeight,
width: s.playerWidth,
videoId: s.videos.stage1,
playerVars: s.playerVars,
events: {
'onReady': $.proxy(MFA.onPlayerReady, MFA),
'onStateChange': $.proxy(MFA.onPlayerStateChange, MFA),
'onError': $.proxy(MFA.onPlayerError, MFA)
}
});
}
,但这表现出同样的问题。随后添加了swfobject.embedSWF
代码作为解决该问题的尝试,因为我们以前已经看到IE与跨域中的API访问相关的问题。
您的代码示例看起来有些关闭。看来您将swfobject.embedSwf
与//www.youtube.com/player_api
一起使用。//www.youtube.com/player_api
脚本仅适用于嵌入的iFrame。如果您使用嵌入的iframe,则应解决您的问题。
详细信息可以在此处找到。https://developers.google.com/youtube/iframe_api_reference
,所以我不得不放下它并回到另一个项目,但是我的一位同事设法找到了一个解决方案。其余的答案是直接从他给我的电子邮件中获取的。
所以这是我们修复此问题的长期版本(非常烦人!)IE问题……事实证明,这是一种更改YouTube Player API在default.aspx页面中调用的方式。
我们更换了这个:
<script src="//www.youtube.com/player_api"></script>
在<script>
标签中使用以下JavaScript:
var tag = document.createElement('script');
tag.src = "//www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
(这就是API参考中指定的方式)。
我还注意到Google指定了iframe_api
,但我们正在使用player_api
。这可能使问题更加复杂,但只是更改没有解决问题的问题。
[我们的技术总监]向我解释的方式是,当页面加载时,原始方法是第一次加载,并且YouTube API有足够的时间来加载init.js Init.js初始化。
但是,当您重新加载页面时,init.js
被缓存,并且可能会在API准备就绪之前加载太快,因此当它尝试触发onYouTubePlayerReady
时失败。这样做的方式仍然从init.js
开始,但也开始同时加载iframe_api
(通过有效地将其插入列表中的第一个脚本标签)。它也可能会稍微连接到IE9的已知问题,在该问题中,Ajax调用可以创建内存泄漏,但不确定。
我在其他浏览器上看到了相同的错误(非常),我认为这是在此处与Google API连接到的任何数据中心之间的RTD波动。如果它不够同步,以使init.js
在API准备就绪之前到达那里,则onYouTubePlayerReady
将失败。但是随后简单的刷新将修复它。
有趣的是,仅将YouTube API放置为第一个脚本标签并没有改变!
所以我想这堂课是,当我们与第三方API,IFRAME和Internet Explorer打交道时,我们需要确保对所有第三方API使用异步加载,尤其是YouTube和Facebook都参与其中。