eliminando el detector de eventos

I have learned this method of passing values with addEventLister. Here is the code:

for (var i:uint = 0; i < asteroids.length; i++)
{

     asteroids[i].x = Math.random() * 450;
     asteroids[i].y = Math.random() * 450;
     asteroids[i].addEventListener(MouseEvent.MOUSE_UP, function(e:MouseEvent){
         changeValue(e, otherArguments);
     });

}



public function changeValue(event:MouseEvent, otherArguments:Object):void
{

    playSound(anote);
    trace(event.currentTarget);

}

but there is no explanation about how to remove the event listener from

  asteroids[i].addEventListener(MouseEvent.MOUSE_UP, function(e:MouseEvent){
     changeValue(e, otherArguments);
 });

preguntado el 03 de mayo de 12 a las 14:05

3 Respuestas

That is because you cannot unhook an anonymous function if you don't have a reference to it. If you'd like, you can always keep a reference around:

asteroidsMouseUpHandler = function(e:MouseEvent){
    changeValue(e, otherArguments);
};

asteroids[i].addEventListener(MouseEvent.MOUSE_UP, asteroidsMouseUpHandler);

asteroids[i].removeEventListener(MouseEvent.MOUSE_UP, asteroidsMouseUpHandler);

Of course, if these things are happening in separate member functions, then you need to define a member variable (var asteroidsMouseUpHandler:Function). At that point, you might just want to create it as a named function instead. You'd also only want to do this once (not in a loop) to avoid clobbering your reference. Really, I am showing this code for illustrative purposes only.

Thinking about this further, you might be doing this because the otherArguments is specific to the particular asteroids[i] instance so that you are actually creating a new anonymous function every time you hook it. In that case, if that is what you really want to do, you can keep track of your anonymous functions in a dictionary:

var asteriodsCallbacks:Dictionary = new Dictionary();

Then, you can keep track of the functions there:

asteroidsCallbacks[asteroids[i]] = asteroidsMouseUpHandler;
asteroids[i].addEventListener(MouseEvent.MOUSE_UP, asteroidsMouseUpHandler);

And then when you want to unhook, you can look it up:

asteroids[i].removeEventListener(MouseEvent.MOUSE_UP, asteroidsCallbacks[asteroids[i]]);

Of course, I am ignoring existential checks for simplicity. You'd have to add that as well.

contestado el 03 de mayo de 12 a las 14:05

Infact, the method I have used was working. But the problem, as mentined, it hooks the function more then one after firt click. That is, for the first click it calls for one time, for the second click second time and so on. I have converted it to your method but it again gives the same result. - osmanraifgunes

fon insatnce: changeValue(variables, variables){trace("result")} the traces on the screen after three clicks are: first click: result. second click: result result. third click: result result result. - osmanraifgunes

I have overcamed that problem like that: ----------------------------------------------------- var beyazTas1:movieclip; beyazTas1.addEventListener(MouseEvent.MOUSE_DOWN, function(e:MouseEvent){tasiSuruklemeyeBasla(e, beyazTas1,1,1);IEventDispatcher(e.currentTarget).removeEventListener(e.type,arguments.callee);}); -------------------------------------------------------- It works fine. But there is a new problem. I am adding the event listener to 25 movieclips. I want to remove all the event listeners from all of them if one of them is used. My method is removing only from the used one. - osmanraifgunes

Why don't you declare the function like normal, rather than in the parameter? You can do the following:

for (var i:uint = 0; i < asteroids.length; i++)
{

     asteroids[i].x = Math.random() * 450;
     asteroids[i].y = Math.random() * 450;
     asteroids[i].addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
     });

}

public function onMouseUp(e:MouseEvent) {
    changeValue(e, otherArguments);
}

public function changeValue(event:MouseEvent, otherArguments:Object):void
{
    playSound(anote);
    trace(event.currentTarget);

}

Puede eliminarlo de la siguiente manera:

asteroids[index].removeEventListener(MouseEvent.MOUSE_UP, onMouseUp)

contestado el 03 de mayo de 12 a las 14:05

I am passing three variables to mouse down event function. After the drag finishes, the three variables will be passed to mouse down event function. there should be a problem using this method in this way. I am passing the movieclip itself to the function to reach easily. Is it possible to pass the movieclip or reaching it, when using your method? - osmanraifgunes

When you add an anonymous function as an event listener, the only time you can reasonably remove that event listener is inside the callback.

public function changeValue(event:MouseEvent, otherArguments:Object):void
{

    playSound(anote);
    trace(event.currentTarget);
    event.currentTarget.removeEventListener(MouseEvent.MOUSE_UP, arguments.callee);

}

Otherwise, you need to have a non-anonymous function in order to remove it.

contestado el 03 de mayo de 12 a las 14:05

I can't say that I agree with this. You can always keep a reference to an anonymous function. There are cases where it makes sense to do so, in fact. - Brian Genisio

@BrianGenisio That's true. I (mistakenly) no longer consider those functions anonymous in my head, which lead to the incorrect wording in my answer. - Sam De Haan

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.