A Flash Developer Resource Site

Results 1 to 8 of 8

Thread: [RESOLVED] Is it possible to pass an argument to the function triggered by an event handler?

  1. #1
    Senior Member
    Join Date
    Jan 2006
    Posts
    133

    resolved [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)???

  2. #2
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    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);

  3. #3
    Senior Member
    Join Date
    Jan 2006
    Posts
    133
    Quote Originally Posted by 5TonsOfFlax View Post

    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?

  4. #4
    a.k.a gltovar deadlock32's Avatar
    Join Date
    May 2001
    Location
    Naperville,IL
    Posts
    489
    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");} , false0true);
    Button2.addEventListener(MouseEvent.CLICK, function(e:MouseEvent){ gotoAndStop("FrameLabel2");} , false0true); 
    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.CLICKNavigatefalse0true);

    Button2.frameLabelTarget 'FrameLabel2';
    Button2.addEventListener(MouseEvent.CLICKNavigatefalse0true);

    // Define the Navigate function
    function Navigate(evt:MouseEvent):void{
        
    gotoAndStop( (evt.currentTarget as YourSpecialButtonClass).frameLabelTarget );


  5. #5
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    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.

  6. #6
    Senior Member
    Join Date
    Jan 2006
    Posts
    133
    Quote Originally Posted by 5TonsOfFlax View Post
    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.

  7. #7
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    What you are missing is the difference between a Function and a Function call.

    Navigate is a Function. Navigate("FrameLabel1") is a function call.

  8. #8
    Senior Member
    Join Date
    Jan 2006
    Posts
    133
    Quote Originally Posted by 5TonsOfFlax View Post
    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
  •  




Click Here to Expand Forum to Full Width

HTML5 Development Center