2012-09-23 36 views
6

¡Necesito esto para youtube api // las funciones callback onStateChange!crear una función javascript programáticamente

Quiero programar funciones que escuchen el evento "onStateChange" emitido por varios jugadores de youtube. Añadiendo el detector funciona ya:

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

La función que necesito para crear sobre la base de la variable playerId ("ytp_1", "ytp_2", ...) es

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

Así, el resultado de la playerId "ytp_1" se vería así:

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

obras también, pero ahora tengo que añadir manualmente para cada jugador, que no es lo que necesito. Quiero crearlos automáticamente cuando un nuevo jugador envía un evento readyState.

Mi problema es que parece que estas funciones deben ser funciones globales para funcionar correctamente. Intenté varias opciones por días. Mi problema es que no sé cómo (si hay una forma) definir una función global, incl. el nombre de la función, programáticamente, basado en otra variable.

Es un fastidio que el ytp no emita un evento que incluye el estado Y el jugador/objetivo. Haría las cosas mucho más fáciles. Todo esto es básicamente la solución porque necesito que todos hagan cosas en todos los cambios de estado.

Si hay una manera mejor/más simple, Háganme saber :) De lo contrario, una solución para esta pregunta es muy bienvenida.

¿Existe alguna forma de volver a programar el evento para hacerlo más "accesible"?

Leí en la especificación que .addEventListener también toma un objeto, así que traté de vincular el evento a un objeto dedicado. Pero, de nuevo, no se activó. Se siente como he probado todo ...

ACTUALIZACIÓN ahora estoy cambiando al jugador iframe (de swfobject) debido a que uno ofrece un evento que incluye playerId y el estado: D Yeahhh !! Después de pasar la semana con el ytplayer equivocado, esto parece un gran avance. También parece que quiere que usemos el reproductor iframe que puede usar html5 dinámicamente cuando es compatible.

Respuesta

4

crea una función que devuelve una función:

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

Luego llama a su fábrica de la función de la hora de configurar el detector de eventos:

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

DEBUGGING

No estoy seguro de por qué eso no funciona, pero aquí está una sugerencia de depuración. Sospecho que es posible que no obtenga el playerId en su controlador 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); 
    } 
} 

¿Podría intentarlo y publicar lo que obtiene de ambas llamadas console.log?

+0

Intenté esto antes y en este momento de nuevo, pero no funciona para mí. El punto es en el momento en que "createStateManager" se llama "playerId" y las variables "ytpStateHelper" provienen de la función principal pero newState no está definida en ese momento, ya que este será el estado ytp cuando se desencadena el evento. –

+0

Debería funcionar ... ¿Has probado la última versión que publiqué (he editado el código poco después de la publicación). – bfavaretto

+0

Cuando llamo a la fábrica en un cambio de estado, esto generará muchas funciones pero no se activará ninguna. La devolución de llamada debe ser un nombre de función y una función con este nombre debe crearse automáticamente. De lo contrario, el disparador no funcionará como lo he probado durante días. Probado, no funciona. Ahora estoy probando algo. en esa direccion. –

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

Esto lo nombra programáticamente, no crea una función que tenga un comportamiento definido por programa, que es lo que el afiche pregunta. –

+0

¡así que lo pegas dentro de la función! Las respuestas no tienen que ser el 100% de lo que el usuario pregunta. Además, este método no es excelente, ya que está inundando el espacio de nombres. Realmente no deberían ser funciones separadas, sino la única función que puede manejar múltiples casos. – epascarello

+0

Como se menciona en un comentario para bfavaretto esto no funcionará. Por alguna razón, el "addEventListener" no puede manejar una ventana [variable] de referencia. Debería funcionar, lo intenté más de dos veces, no es así. –

2

1) Se puede crear el objeto Función new Function([params], "BODY") Así que usted puede combinar cuerpo de su función como variable de cadena y poner en su calidad de órgano

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

2) y nuevo puede crear dinámicamente el nombre y el cuerpo

Ejemplo

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"); 

Puede llamar a su nueva función:

globalObject[nameFn](10,20); 

Resultado: 15

Tenga en cuenta que en el cuerpo de su función puede obtener params a través de la colección arguments

+0

Gracias por la idea pero el problema es que necesito definir programáticamente la función NAME. Basado en la función llamada Sé que llamó itp. Acabo de comprobar la API apilada y parece que una es mejor ya que el evento proporciona estado y playerId, que es lo que necesitaba. –

+0

Por favor, mira actualización, espero que esto te ayude –

0

He aquí una manera de crea una función proxy nombrada que ejecuta otra función con el contexto que proporcionas.

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(); 

La solución anterior crea una función que puede crear y devolver una función nombrada que ejecutó lo que quisiera. Si no proporciona el contexto, supondrá que el objeto de la ventana es como una función anónima normal. Para crear la solución que quería, haría:

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

Donde varName podría ser cualquier prefijo programático que desee. Al invocar ytp_1_StateManager() pasaría su valor newState y el código llamaría a ytpStateHelper con su nombre de variable y newState.

Espero que esto ayude.

Cuestiones relacionadas