以编程方式创建一个javascript函数

时间:2012-09-23 23:57:17

标签: javascript youtube youtube-api youtube-javascript-api

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

我想以编程方式创建将监听" onStateChange"几个youtube播放器发出的事件。添加侦听器已经起作用了:

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 Yeahhh !!在错误的ytplayer度过了一周之后,这感觉就像是一次伟大的进步。似乎也希望我们使用iframe播放器,它可以在支持时动态使用html5。

4 个答案:

答案 0 :(得分:4)

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

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两个电话中获得的内容吗?

答案 1 :(得分:2)

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

实施例:     var twoNumAverage = new Function(“x”,“y”,“return(x + y)/ 2”)     console.log(twoNumAverage(3,7))

2)new可以动态创建名称和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

获取参数

答案 2 :(得分:0)

window["foo"+"bar"] = function(){ console.log("foobar is called"); }

答案 3 :(得分: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。

希望这有帮助。