因此,我们有一个包含YouTube视频的Facebook标签应用程序(可能不相关)。
第一次从空缓存加载页面时,一切正常。但是,在后续页面加载时,一旦视频停止加载,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>
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 embed code。
我们最初使用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在跨iframe的域中进行API访问时过度偏执的问题。
答案 0 :(得分:0)
您的代码示例看起来有些偏差。您似乎正在swfobject.embedSwf
使用//www.youtube.com/player_api
。 //www.youtube.com/player_api
脚本仅适用于iframe嵌入。如果你使用iframe嵌入它应该解决你的问题。
详细信息可以在这里找到。 https://developers.google.com/youtube/iframe_api_reference
答案 1 :(得分:0)
所以我不得不放下这个并回到另一个项目,但我的一位同事设法找到了解决方案。其余的答案直接来自他给我的电子邮件。
所以这里是我们如何修复这个(非常讨厌!)IE问题的长版本...事实证明这是改变在default.aspx页面中调用YouTube Player API的方式。
我们取代了这个:
<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 reference中指定的方式)。
我还注意到Google指定了iframe_api
,但我们使用的是player_api
。这可能会使问题复杂化,但只是改变它并没有解决它。
[我们的技术总监]向我解释的方式是,第一次加载页面时原始方式很好,因为所有内容都是新加载的,并且在API初始化之前,YouTube API有足够的时间加载。
但是当你重新加载页面时,在API准备好之前,init.js
被缓存并且可能加载太快,因此在尝试触发onYouTubePlayerReady
时失败。以上述方式执行仍然从init.js
开始,但也开始同时加载iframe_api
(通过有效地将其作为列表中的第一个脚本标记插入)。它也可能与known issue with IE9 where AJAX calls can create a memory leak略有关联,但不确定。
我在其他浏览器上间歇性地看到同样的错误(非常),我认为这与此处与Google API连接的数据中心之间的RTDs之间存在波动。如果在{API}准备就绪之前init.js
已经足够同步,那么onYouTubePlayerReady
将失败。但是,简单的刷新就能解决它。
有趣的是,仅将YouTube API作为第一个脚本标记并没有什么区别!
所以我想我们的教训是,当我们处理第三方API,iframe和Internet Explorer时,我们需要确保为所有第三方API使用异步加载,特别是如果涉及到YouTube和Facebook