通过ajax实现youtube iframe api

通过ajax实现youtube iframe api,youtube,youtube-api,Youtube,Youtube Api,我有一个s系统,其中主要内容通过ajax加载,位于主“框架”的一个div内 在某些页面中,我需要跟踪用户何时完成视频播放。我正在尝试使用youtube iframe api。它工作正常,但我正在做一些奇怪的事情 主要问题是:当用户观看完视频后,每个页面上发生的动作都不一样,而且不知何故,API正在堆叠所有函数并同时运行 举例来说,我有通过ajax加载的第一个页面,并有以下代码段加载youtube视频: <script> // 2. This code loads the IFra

我有一个s系统,其中主要内容通过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>

// 2. 此代码异步加载IFrame播放器API代码。
如果(window.YT)
{
window.YT=未定义;
}
var tag=document.createElement('script');
tag.src=”https://www.youtube.com/iframe_api";
var firstScriptTag=document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(标记,firstScriptTag);
// 3. 此函数用于创建(和YouTube播放器)
//API代码下载后。
var player=未定义;
函数onyoutubeiframeapiredy(){
player=新的YT.player('divVideo'{
playerapiid:'somecode',
高度:“309”,
宽度:“439”,
videoId:“somecode”,
活动:{
“onStateChange”:onPlayerStateChange
}
});
}
// 4. 当播放器的状态改变时,API调用此函数。
//该功能指示播放视频时(状态=1),
//玩家应该玩六秒钟,然后停下来。
函数onPlayerStateChange(事件){
如果(event.data==YT.PlayerState.end){
actionToScreen1()
}
}
它工作正常。但是,我加载了第二页的内容,现在问题开始了:

<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>

// 2. 此代码异步加载IFrame播放器API代码。
如果(window.YT)
{
window.YT=未定义;
}
var tag=document.createElement('script');
tag.src=”https://www.youtube.com/iframe_api";
var firstScriptTag=document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(标记,firstScriptTag);
// 3. 此函数用于创建(和YouTube播放器)
//API代码下载后。
var player=未定义;
函数onyoutubeiframeapiredy(){
player=新的YT.player('divVideo'{
playerapiid:“另一个代码”,
高度:“309”,
宽度:“439”,
videoId:“另一个代码”,
活动:{
“onStateChange”:onPlayerStateChange
}
});
}
// 4. 当播放器的状态改变时,API调用此函数。
//该功能指示播放视频时(状态=1),
//玩家应该玩六秒钟,然后停下来。
函数onPlayerStateChange(事件){
如果(event.data==YT.PlayerState.end){
actionToScreen2()
}
}

当我的屏幕2上的视频结束时,onPlayerStateChange被调用两次,一次调用actionToScreen1,另一次调用actionToScreen2。看起来我只是通过ajax加载容器,函数是全局存储的,但是我找不到位置,也找不到区分调用哪个函数的方法。如何解决这个问题?

如果不查看实际页面,很难准确说出所有不同变量的作用域,但这里有一些一般建议

由于每次通过AJAX加载新内容时,您都没有完全重新加载网页,所以只需加载
https://www.youtube.com/iframe_api
library一次,从某个“父”页面删除,而不是尝试删除它,然后在每次引入新内容时重新加载它

作为一种扩展,当您在拉入新内容时,不要监听
onyoutubeiframeapiredy
事件。一个好的模式是调用一个方法来提示视频;在该方法中,如果定义了
player
(设置为您的
YT.player
实例),则调用
player.cueVideo()
/
player.loadVideo()
。如果尚未定义
player
,则加载
https://www.youtube.com/iframe_api
library,并定义一个
onyoutubeiframeapiredy
函数,该函数将负责在加载库后使用正确的视频id调用
YT.Player
构造函数


下面是一些JavaScript代码的一个例子,它几乎做到了这一点:它使用RequireJS模块,因此语法与您正在做的略有不同,但总体思路是相同的。您可以通过player.playVideo(containerDiv,videoId)从使用该模块的外部JS文件调用该代码。

在尝试了各种解决方案后,我放弃了,并使用了一个完美的解决方案

<iframe id="video-recorder" src="/site/recorder" scrolling="no"
            style="width: 400px; height: 260px; overflow: hidden;">
</iframe>

其余的代码,如事件等,可以在官方页面上找到:

在Screen2加载后是否可以删除Screen1DOM?
<!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
        }
    });
}