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



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 Yeahhh!!在与错误的ytplayer相处了一周之后,这感觉是一个巨大的进步。yt似乎也希望我们使用iframe播放器,它可以在支持的情况下动态使用html5。

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

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

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

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

调试

我不知道为什么不起作用,但这里有一个调试建议。我怀疑您可能没有在onYouTubePlayerReady处理程序上获得playerId

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)您可以创建Function对象new Function([params], "BODY")所以您可以将函数的主体组合为字符串变量,并作为body 放入

示例:var twoNumAverage=新函数("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获取参数

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

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。

希望这能有所帮助。

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

相关内容

  • 没有找到相关文章

最新更新