我的系统主要内容是通过ajax加载的,位于主“框架”的div内。
在某些页面中,我需要跟踪用户何时播放视频。我正在尝试使用youtube iframe api。它运作正常,但我正在运行一些奇怪的事情。
主要问题:当用户完成观看视频时发生的操作在每个页面上都不同,并且不知何故,API正在堆叠所有功能并立即运行。
例如,我有第一页,通过ajax加载,并有此片段加载YouTube视频:
<script>
// 2. This code loads the IFrame Player API code asynchronously.
if (window.YT)
{
window.YT = undefined;
}
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
// 3. This function creates an <iframe> (and YouTube player)
// after the API code downloads.
var player = undefined;
function onYouTubeIframeAPIReady() {
player = new YT.Player('divVideo', {
playerapiid: 'somecode',
height: '309',
width: '439',
videoId: 'somecode',
events: {
'onStateChange': onPlayerStateChange
}
});
}
// 4. The API calls this function when the player's state changes.
// The function indicates that when playing a video (state=1),
// the player should play for six seconds and then stop.
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.ENDED ) {
actionToScreen1()
}
}
</script>
一切正常。但是,我加载了第二页的内容,现在问题就开始了:
<script>
// 2. This code loads the IFrame Player API code asynchronously.
if (window.YT)
{
window.YT = undefined;
}
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
// 3. This function creates an <iframe> (and YouTube player)
// after the API code downloads.
var player = undefined;
function onYouTubeIframeAPIReady() {
player = new YT.Player('divVideo', {
playerapiid: 'anothercode',
height: '309',
width: '439',
videoId: 'anothercode',
events: {
'onStateChange': onPlayerStateChange
}
});
}
// 4. The API calls this function when the player's state changes.
// The function indicates that when playing a video (state=1),
// the player should play for six seconds and then stop.
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.ENDED ) {
actionToScreen2()
}
}
</script>
当我的screen2上的视频完成时,onPlayerStateChange被调用两次,一次调用actionToScreen1和其他actionToScreen2。看起来我只是通过ajax加载容器,函数存储有点全局,但我找不到位置,也无法找到区分调用哪个函数的方法。我该如何解决这个问题?
答案 0 :(得分:2)
如果不查看您的实际页面,很难确切知道所有不同变量的范围,但这里有一些一般建议。
由于每次通过AJAX加载一些新内容时都没有完全重新加载网页,只需从一些“父”页面加载https://www.youtube.com/iframe_api
库,而不是尝试删除它然后每次拉入新内容时重新加载它。
作为其延伸,当您提取新内容时,请勿听取onYouTubeIframeAPIReady
个事件。一个好的模式是调用一个方法来定位一个视频;在该方法中,如果定义了player
(设置为YT.Player
实例),则调用player.cueVideo()
/ player.loadVideo()
。如果尚未定义player
,则在此时加载https://www.youtube.com/iframe_api
库,并定义一个onYouTubeIframeAPIReady
函数,该函数将负责使用正确的YT.Player
构造函数调用加载库后视频ID。
以下是一些JavaScript代码的例子:https://code.google.com/p/youtube-direct-lite/source/browse/static/js/ytdl/player.js它使用RequireJS模块,所以语法与你正在做的有点不同,但总体思路是一样的。您可以从通过player.playVideo(containerDiv, videoId)
答案 1 :(得分:1)
尝试各种解决方案后,我放弃了,并使用了完美的解决方法。
<iframe id="video-recorder" src="/site/recorder" scrolling="no"
style="width: 400px; height: 260px; overflow: hidden;">
</iframe>
iframe
将负责重新加载api和所有内容..
这是在iframe中。确保您具有相同的大小,以便所有内容都可见:
<!doctype html><html><head>
<meta charset="utf-8">
<style>html,body { margin: 0; padding: 0; overflow: hidden; width: 400px; height: 260px; }</style>
<script src="http://www.youtube.com/iframe_api"></script>
<body>
<div id="widget"></div>
<div id="player"></div>
<script>
var widget;
var player;
function onYouTubeIframeAPIReady() {
widget = new YT.UploadWidget('widget', {
width: 400,
height: 260,
events: {
'onUploadSuccess': onUploadSuccess,
'onProcessingComplete': onProcessingComplete
}
});
}
其他代码,如事件等,可在官方网页上找到:https://developers.google.com/youtube/youtube_upload_widget