Pasar parámetros a la función dentro del addEventListener

  Compatibilidad del artículo: ActionScript 2.0.   ActionScript 3.0.   

Pasar parámetros a la función dentro del addEventListener

Para recoger eventos de un elemento con ActionScript, disponemos del método addEventListener, su sintaxis sería de la siguiente forma:

componente.addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false);


Donde:
componenteSería el objeto que detectaría el evento.
type:StringEl tipo de evento que se debe detectar.
listener:FunctionLa variable función que se ejecutará al activarse el evento del objeto.
useCapture:Boolean = falseSi el evento se ejecutará sólo en fase de captura (true), o en cualquier momento (false, por defecto).
priority:int = 0Prioridad de ejecución, por defecto 0.
useWeakReference:Boolean = falseSi la referencia al detector es fuerte o débil, si es débil (true, recomendado), al ser eliminado el objeto receptor, el recolector de datos eliminará el detector del evento.Si es fuerte (false, por defecto), sólo se eliminará el detector del evento de forma explicita (Con removeEventListener).


El parámetro que nos interesa, es por lo tanto el listener que debe ser una variable "Function", un ejemplo de como se podría hacer es:

// Ejemplo de llamada al evento:
componente.addEventListener(evento, funcion_receptora);

// Ejemplo de recepción del evento:
function funcion_receptora(evt:Event):void {
    
    trace("Se ha ejecutado la función receptora a un evento de una instancia.");
    
}


Como se puede ver, el método addEventListener, pasa por defecto como parámetro una variable "Event" (MouseEvent, TimerEvent, ...), sin embargo si queremos pasar mas parámetros, en principio, parece que no se puede, ya que hacer algo como componente.addEventListener(evento, funcion_receptora(1, 3));, haría que se ejecutase "funcion_receptora(1, 3)", por lo que devolvería un valor null y un consiguiente error ya que se espera una variable Function.

Una forma muy sencilla de solucionar esto sería recubrir nuestra llamada mediante una función vacía de una forma de tipo:

// Llamada a "funcion_receptora"
componente.addEventListener(evento, function(){funcion_receptora(variable1, variable2, variableX)});

// Llamada a "funcion_receptora" con el evento
componente.addEventListener(evento, function(evt:Event){funcion_receptora(evt, variable1, variable2, variableX)});


Esto en principio debería funcionar siempre, sin embargo, si las variables pasadas, fueran modificadas a posteriori, el valor cambiaría, por ejemplo:

var iCont:int = 0;

// iCont vale 0, se crea la definición del evento
btnXXX.addEventListener(MouseEvent.CLICK, function(evt2:MouseEvent){mvXXX_onClick(evt2, iCont);});

// iCont Vale 1
iCont ++;

function mvXXX_onClick(evt:MouseEvent, iX:int):void
{
    // Pintaría 1
    trace("Valor pasado: " + iX);
}


La interpretación de Flash sería:

// Primero las lineas de código (asteriscos todavía no)
var iCont:int = 0;

// iCont vale 0, se crea la definición del evento
btnXXX.addEventListener(MouseEvent.CLICK, function(evt2:MouseEvent){***************************});

// iCont Vale 1
iCont ++;

// -------------------------------------------------------
// Después las funciones

// Referencia a función anónima (asteriscos)

function(evt2:MouseEvent){mvXXX_onClick(evt2, iCont);}

function mvXXX_onClick(evt:MouseEvent, iX:int):void
{
    // Pintaría 1
    trace("Valor pasado: " + iX);
}



Por esto, esta opción no sería la opción mas recomendable, ya que nos podría dar problemas, por lo que sólo nos queda una última alternativa, llamar a una función intermedia que devuelva una función con los parámetros que nosotros queremos.

El ejemplo, recibe primero una variable Function que sería la función final y a continuación todas las posibles variables que son recogidas con el tipo de datos ... (rest), que permite recibir cualquier cantidad y tipo de variables y las convierte en una matriz.
Posteriormente Devuelve una función que recoge el evento y le añade el resto de las variables pasadas a la llamada de la función final.

La diferencia entre el primer método y este es que al llegar a la llamada de la función, ahora la ejecuta, ya que no es un valor pasado de tipo function, sino una orden de ejecución de una función que devuelve la variable Function, pero con los datos ya tratados, por lo que lo que se haga con ellos, ya no afectará.


ActionScript:
// Copyright © McAnam.com
// http://www.mcanam.com/articulos/Flash.php?id=3

btnComienzo1.buttonMode=true;
btnComienzo2.buttonMode=true;
btnComienzo3.buttonMode=true;

btnComienzo1.addEventListener(MouseEvent.CLICK, EventoTransicion(navegar, "http://www.mcanam.com/foros/"));
btnComienzo2.addEventListener(MouseEvent.CLICK, EventoTransicion(navegar, "http://www.mcanam.com/aplicaciones/librovisitas/descripcion.php"));
btnComienzo3.addEventListener(MouseEvent.CLICK, EventoTransicion(navegar, "http://www.mcanam.com/librovisitas/lvisitas.php"));

function navegar(evt:MouseEvent, sDireccion:String):void {
    
    navigateToURL(new URLRequest(sDireccion), "_blank");
    
}

function EventoTransicion(funcion:Function, ... args):Function{
    
    return function(evento:Event):void{
        funcion.apply(funcion, new Array(evento).concat(args));
    }

}


Ejemplo:

Links relacionados:
Formulario de contacto en Flash con adjunto
Importar vídeo y reproducir streaming con flash
Cargar y presentar variables de fichero externo
Ejecutar JavaScript desde Flash por URL


Para cualquier duda, consulta, sugerencia, opinión, colaboración, etc; no dude en ponerse en contacto con nosotros

Copyright © 2002-2017 [McAnam]. Reservados todos los derechos.
www.mcanam.com