-
[RESOLVED] Is it possible to pass an argument to the function triggered by an event handler?
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, like so:
Code:
// Define the Navigate function
function Navigate(myLabel){
gotoAndStop(myLabel);
}
// code on Button1
on(release){
Navigate("FrameLabel1");
}
// code on Button2
on(release){
Navigate("FrameLabel2");
}
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 below).
Code:
// Add listeners to buttons
Button1.addEventListener(MouseEvent.CLICK, Navigate, false, 0, true);
Button2.addEventListener(MouseEvent.CLICK, Navigate, false, 0, true);
// Define the Navigate function
function Navigate(evt:MouseEvent):void{
switch(evt.target.name){
case "Button1":
gotoAndStop("FrameLabel1");
break;
case "Button2":
gotoAndStop("FrameLabel2");
break;
default:
gotoAndStop(1)
}
}
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:
Code:
// Add listeners to buttons
Button1.addEventListener(MouseEvent.CLICK, Navigate("FrameLabel1"), false, 0, true);
Button2.addEventListener(MouseEvent.CLICK, Navigate("FrameLabel2"), false, 0, true);
// Define the Navigate function
function Navigate(myLabel){
gotoAndStop(myLabel);
}
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)???
-
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:
var buttonArgs:Dictionary = new Dictionary();
buttonArgs[button1] = "FrameLabel1";
buttonArgs[button2] = "FrameLabel2";
function navigate(e:Event):void{
gotoAndStop(buttonArgs[e.target]);
}
Or you could create a function which creates specific functions.
Code:
function makeNavigate(myLabel:String):Function{
return function(e:Event):void{
navigate(myLabel); //navigate is defined elsewhere
}
}
button1.addEventListener(MouseEvent.CLICK, makeNavigate("FrameLabel1"), false, 0, true);
Or you could automate the process of creating the indirection functions by using FunctionUtils:
http://cosmodro.me/blog/2008/aug/26/...ity-functions/
Code:
button1.addEventListener(MouseEvent.CLICK, FunctionUtils.closurizeEventHandler(navigate, "FrameLabel1"), false, 0, true);
-
Originally Posted by 5TonsOfFlax
Or you could create a function which creates specific functions.
Code:
function makeNavigate(myLabel:String):Function{
return function(e:Event):void{
navigate(myLabel); //navigate is defined elsewhere
}
}
button1.addEventListener(MouseEvent.CLICK, makeNavigate("FrameLabel1"), false, 0, true);
So, using your example... why does this work:
Code:
Button1.addEventListener(MouseEvent.CLICK, makeNavigate("FrameLabel1"), false, 0, true);
Button2.addEventListener(MouseEvent.CLICK, makeNavigate("FrameLabel2"), false, 0, true);
function makeNavigate(myLabel:String):Function{
return function(evt:MouseEvent):void{
gotoAndStop(myLabel);
}
}
But this returns a 1067 compiler error:
Code:
Button1.addEventListener(MouseEvent.CLICK, makeNavigate("FrameLabel1"), false, 0, true);
Button2.addEventListener(MouseEvent.CLICK, makeNavigate("FrameLabel2"), false, 0, true);
function makeNavigate(myLabel:String):void{
gotoAndStop(myLabel);
}
Why do I need to "bury" the gotoAndStop() action in another function? Why does the makeNavigate function need to return a Function data type instead of just being "void" and executing the gotoAndStop() action itself?
-
a.k.a gltovar
here are some other solutions for you:
Method 1 (quick but dirty): you can put function IN the event listener:
PHP Code:
Button1.addEventListener(MouseEvent.CLICK, function(e:MouseEvent){ gotoAndStop("FrameLabel1");} , false, 0, true);
Button2.addEventListener(MouseEvent.CLICK, function(e:MouseEvent){ gotoAndStop("FrameLabel2");} , false, 0, true);
Method 2 (longer but a lil cleaner): create a variable in the button for you to access
PHP Code:
// Add listeners to buttons
var Button1:YourSpecialButtonClass;
var Button2:YourSpecialButtonClass;
Button1.frameLabelTarget = 'FrameLabel1';
Button1.addEventListener(MouseEvent.CLICK, Navigate, false, 0, true);
Button2.frameLabelTarget = 'FrameLabel2';
Button2.addEventListener(MouseEvent.CLICK, Navigate, false, 0, true);
// Define the Navigate function
function Navigate(evt:MouseEvent):void{
gotoAndStop( (evt.currentTarget as YourSpecialButtonClass).frameLabelTarget );
}
-
Both of deadlock's solutions are also good.
To answer your question, you must "bury" the gotoAndStop because addEventListener requires a Function as the second argument. If you did it the way you propose, the gotoAndStop would be executed at the time of the addEventListener call, and not when the event actually happens. Further, since the result of that function is void, you get the compile error you saw.
-
Originally Posted by 5TonsOfFlax
To answer your question, you must "bury" the gotoAndStop because addEventListener requires a Function as the second argument.
Sorry for dragging on... just trying to get my head around this stuff...
So, I understand that the addEventListener requires a Function as the 2nd argument. However, the code for the addEventListener is the exact same for each of those examples:
Code:
Button1.addEventListener(MouseEvent.CLICK, makeNavigate("FrameLabel1"), false, 0, true);
So, to me the difference is in how you end up defining the return data type of the makeNavigate function... it either gets a ":void" or ":Function" as the return data type. Using ":void" fails.
So, my confusion comes from looking back at my first post, the example using the switch statement, that makeNavigate function works fine and returns ":void"
Code:
Button1.addEventListener(MouseEvent.CLICK, makeNavigate, false, 0, true);
Button2.addEventListener(MouseEvent.CLICK, makeNavigate, false, 0, true);
function makeNavigate(evt:MouseEvent):void{
switch(evt.target.name){
case "Button1":
gotoAndStop("FrameLabel1");
break;
case "Button2":
gotoAndStop("FrameLabel2");
break;
default:
trace("default");
}
}
So, why does this makeNavigate function work (notice the ":void"), but the previous one does not?
Last edited by badaboom55; 03-31-2009 at 06:01 PM.
-
What you are missing is the difference between a Function and a Function call.
Navigate is a Function. Navigate("FrameLabel1") is a function call.
-
Originally Posted by 5TonsOfFlax
What you are missing is the difference between a Function and a Function call.
Navigate is a Function. Navigate("FrameLabel1") is a function call.
Darn skippy! Wow. Good job finding the right words to make it click for me! I actually feel kind of stupid now.
Ok, so by writing 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.
By adding parens () after Navigate (and any argument contained therein), that means the listener is actually trying to call the Navigate function at the time of the addEventListener call, which is ok, but it needs to get back a function in return...
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|