Skip to main content
March 31, 2009
Answered

Is it possible to pass an argument to the function triggered by an event handler?

  • March 31, 2009
  • 1 reply
  • 506 views
Hello All,
Trying to migrate my way of thinking from AS2 to CS4/AS3.
Ok, I have 2 buttons on the stage. Each button does almost the same thing, so I want to create a single function, and each button calls that same function (we'll name that function "Navigate")... however, the function will need to end up doing something different dependant on which button was clicked.
So, previously, in AS2, I would've added some code onto the buttons themselves with on(release) methods (see CODE EXAMPLE 1)

So, each button effectively calls the Navigate function, and passes a different frame label to the function.
Now, I'm trying to recreate this functionality in AS3. As you all know, on(release) has been done away with (still don't know why), but we now have to use event handlers, so I'm trying to figure out a way to pass a different frame label argument to the Navigate function. Currently I can achieve that by using a switch statement to test which button was clicked, and act accordingly (see CODE EXAMPLE 2).

In this over-simplified example, this works fine, but in the real world I'm going to have more than 2 buttons, and the Navigate function would probably be much more complicated...
So, I would like to be able to pass an argument(s) (like in the AS2 example) to the Navigate function... perhaps in the addEventListener() method? I tried this, but got compiler errors (see CODE EXAMPLE 3):

The Million Dollar Question:
Is it possible to dynamically pass/change an argument(s) to a function which is triggered by an event listener? (Or is the event that triggered the function the only argument you can have?)
If this isn't possible, I'd greatly like to hear how you folks would handle this (other than having a switch statement with 12 cases in it)???
This topic has been closed for replies.
Correct answer
I've found a couple solutions that I'll post below for prosperity...

You could create a Dictionary keyed by the prospective event targets and store any information in there you want associated with them. Then the navigate function can check that dictionary to get it's parameters:

// Code //
Button1.addEventListener(MouseEvent.CLICK, Navigate, false, 0, true);
Button2.addEventListener(MouseEvent.CLICK, Navigate, false, 0, true);

var buttonArgs:Dictionary = new Dictionary();
buttonArgs[Button1] = "FrameLabel1";
buttonArgs[Button2] = "FrameLabel2";

function Navigate(e:MouseEvent):void{
gotoAndStop(buttonArgs[e.target]);
}


This in my eyes, is about the same amount of work as writing a long switch statement, but a little more elegant I suppose.

I had a little trouble understanding the next solution, because I didn't quite understand an important piece of information about event listeners. The addEventListener () requires a Function as the 2nd argument passed to it.
It didn't quite click until someone pointed it out to me: Navigate is a Function... Navigate("FrameLabel1") is a Function call...

So by writing just Navigate, I'm not actually calling the function at the time of the addEventListener call, I'm just supplying the event listener with a reference to the name of the function. Then, when the listener is triggered, the listener will call (and pass a MouseEvent argument to) the Navigate function.

Conversely, by writing Navigate("FrameLabel1") as the 2nd argument, the event listener trys to execute the Navigate function at the time the addEventListener is instantiated. And, since, in this example, the Navigate function returned as ":void" a compile error would occur because as I stated, an event listener requires a Function data type as the 2nd argument. This would basically be like writing addEventListener(MouseEvent.Click, void, false, 0, true)
However, there is a way around this... basically, instead of defining the Navigate function as returning a void data type, you define it as returning a Function data type, and then nest another function (which actually contains the actions you want to perform) inside of it.

Button1.addEventListener(MouseEvent.CLICK, Navigate("FrameLabel1"), false, 0, true);
Button2.addEventListener(MouseEvent.CLICK, Navigate("FrameLabel2"), false, 0, true);

function Navigate(myLabel:String):Function{
return function(evt:MouseEvent):void{
gotoAndStop(myLabel);
}
}


1 reply

New Participant
March 31, 2009
Can't do it. The event listener does not support it natively.

But there are a few ways to do this. You can have custom events with data attached to them or have your button extend the eventdispatcher class and override the default addEventListener method.



Correct answer
April 1, 2009
I've found a couple solutions that I'll post below for prosperity...

You could create a Dictionary keyed by the prospective event targets and store any information in there you want associated with them. Then the navigate function can check that dictionary to get it's parameters:

// Code //
Button1.addEventListener(MouseEvent.CLICK, Navigate, false, 0, true);
Button2.addEventListener(MouseEvent.CLICK, Navigate, false, 0, true);

var buttonArgs:Dictionary = new Dictionary();
buttonArgs[Button1] = "FrameLabel1";
buttonArgs[Button2] = "FrameLabel2";

function Navigate(e:MouseEvent):void{
gotoAndStop(buttonArgs[e.target]);
}


This in my eyes, is about the same amount of work as writing a long switch statement, but a little more elegant I suppose.

I had a little trouble understanding the next solution, because I didn't quite understand an important piece of information about event listeners. The addEventListener () requires a Function as the 2nd argument passed to it.
It didn't quite click until someone pointed it out to me: Navigate is a Function... Navigate("FrameLabel1") is a Function call...

So by writing just Navigate, I'm not actually calling the function at the time of the addEventListener call, I'm just supplying the event listener with a reference to the name of the function. Then, when the listener is triggered, the listener will call (and pass a MouseEvent argument to) the Navigate function.

Conversely, by writing Navigate("FrameLabel1") as the 2nd argument, the event listener trys to execute the Navigate function at the time the addEventListener is instantiated. And, since, in this example, the Navigate function returned as ":void" a compile error would occur because as I stated, an event listener requires a Function data type as the 2nd argument. This would basically be like writing addEventListener(MouseEvent.Click, void, false, 0, true)
However, there is a way around this... basically, instead of defining the Navigate function as returning a void data type, you define it as returning a Function data type, and then nest another function (which actually contains the actions you want to perform) inside of it.

Button1.addEventListener(MouseEvent.CLICK, Navigate("FrameLabel1"), false, 0, true);
Button2.addEventListener(MouseEvent.CLICK, Navigate("FrameLabel2"), false, 0, true);

function Navigate(myLabel:String):Function{
return function(evt:MouseEvent):void{
gotoAndStop(myLabel);
}
}