6

youtube api // onStateChange 回调函数需要这个!

我想以编程方式创建将监听几个 youtube 播放器发出的“onStateChange”事件的函数。添加监听器已经生效:

function onYouTubePlayerReady(playerId) {
  var ytpStateManager = playerId +"_StateManager";
  document.getElementById(playerId).addEventListener("onStateChange", ytpStateManager );
...

我需要根据 playerId 变量(“ytp_1”,“ytp_2”,...)创建的函数是

function ytpStateManager(newState) {
  ytpStateHelper(playerId , newState);
}

因此 playerId "ytp_1" 的结果如下所示:

function ytp_1_StateManager(newState) {
  ytpStateHelper("ytp_1", newState);
}

也可以,但现在我需要为每个玩家手动添加它们,这不是我需要的。我想在新玩家发送 readyState 事件时自动创建它们。

我的问题是,这些函数似乎需要成为全局函数才能正常工作。我已经尝试了好几天了。我的问题是我不知道如何(如果有办法)定义一个全局函数,包括。函数名,以编程方式,基于另一个变量。

令人遗憾的是,ytp 没有发出包含状态和玩家/目标的事件。会让事情变得容易得多。所有这些基本上都是解决方法,因为我需要在所有 stateChanges 上做所有事情。

如果有更好/更简单的方法,请告诉我:) 否则非常欢迎这个问题的解决方案。

也许有一种方法可以重新安排事件,使其更“可访问”?

我在规范中读到 .addEventListener 也接受一个对象,所以我尝试将事件绑定到一个专用对象。但同样,它没有被触发。感觉就像我测试了一切......

更新 我现在切换到 iframe 播放器(来自 swfobject),因为它提供了一个包含 playerId 和 state 的事件:D 耶!在与错误的 ytplayer 一起度过了一周之后,这感觉像是一个巨大的进步。似乎 yt 希望我们使用 iframe 播放器,它可以在支持时动态使用 html5。

4

4 回答 4

5

您创建一个返回函数的函数:

function createStateManager(playerId) {
    return function (newState) {
        ytpStateHelper(playerId , newState);
    }
}

然后在设置事件侦听器时调用函数工厂:

var player = document.getElementById(playerId);
player.addEventListener("onStateChange", createStateManager(playerId));

调试

我不确定为什么这不起作用,但这里有一个调试建议。我怀疑你可能没有得到playerId你的onYouTubePlayerReady处理程序。

function onYouTubePlayerReady(playerId) {
    console.log('Player ready. The player id is: ' + playerId);
    var ytpStateManager = playerId +"_StateManager";
    var player = document.getElementById(playerId);
    player.addEventListener("onStateChange", createStateManager(playerId));
}

function createStateManager(playerId) {
    return function (newState) {
        console.log('State changed for player ' + playerId + '. New state is ' + newState);
        ytpStateHelper(playerId , newState);
    }
}

您可以尝试一下,然后发布您从两个console.log电话中获得的信息吗?

于 2012-09-24T00:00:04.140 回答
2

1)您可以创建函数对象 new Function([params], "BODY") 因此您可以将函数的主体组合为字符串变量并作为 BODY 放入

示例: var twoNumAverage = new Function("x", "y", "return (x + y)/2") console.log(twoNumAverage(3,7))

2)new可以动态创建name和BODY

例子

var globalObject ={};
var nameFn ='MyNewFunction';

var createFn  = function(object,functionName, Body){
   object[functionName]= new Function(Body); 
}

createFn(globalObject,nameFn,"return (arguments[0] + arguments[1])/2");

你可以调用你的新函数:

globalObject[nameFn](10,20);

结果:15

请注意,在您的函数中,您可以通过集合获取参数arguments

于 2012-09-24T11:54:54.030 回答
0

这是一种创建命名代理函数的方法,该函数使用您提供的上下文执行另一个函数。

function createNamedProxy(name, fn, context) { 
  var template = [
          '(function @name() {',
          '  @name.fn.apply(@name.context || window, arguments);',
          '})'
      ].join('').replace(/@name/g, name),

  result = eval(template);
  result.fn = fn;
  result.context = context;

  return result;
}  

// Example Usage
var anonymous = function() { alert( document === this ); },
    named = createNamedProxy('Named', anonymous, document);

// Will alert 'true'
named();

上面的解决方案创建了一个函数,该函数可以创建并返回一个命名函数,该函数执行您想要的任何操作。如果您不提供上下文,它将像普通匿名函数一样假定窗口对象。要创建您想要的解决方案,您可以:

var varName = 'ytp_1';
window[varName + '_StateManager'] = 
    createNamedProxy(varName + '_StateManager', function(newState) {
      ytpStateHelper(varName, newState);
    });

其中 varName 可以是您想要的任何编程前缀。调用 ytp_1_StateManager() 时,您将传入您的 newState 值,代码将使用您的变量名和 newState 调用 ytpStateHelper。

希望这可以帮助。

于 2013-04-13T23:19:01.093 回答
0
window["foo"+"bar"] = function(){ console.log("foobar is called"); }
于 2012-09-24T00:00:40.240 回答