Ultrashock Forums > Flash > ActionScript
AS3: adding parameter to eventListener

You are currently viewing our website as a guest which gives you limited access to forums, files and other resources.

Click here to join now for free, and start interacting with our members, download files and much more!

Click here if you are looking for our Flash files and other professional assets.
 
Post Reply | View first unread | Rate Thread Search this Thread | Thread Tools | Display Modes

#1
Bookmark and Share!
AS3: adding parameter to eventListener
Old 2008-05-29

hi everybody.


i'd like to know how to pass a parameter to my function through an eventListener.
to illustrate, I've made this example:
http://campjohn.dk/AS3/addingParamet...ntListener.swf

by clicking the boxes on the left, the bigBox centrered changes color.
nice!
right now, I have to use a if else-loop:

Code:
//imports
import caurina.transitions.Tweener;

this.blueBox.addEventListener(MouseEvent.CLICK, changeColor);
this.redBox.addEventListener(MouseEvent.CLICK, changeColor);
this.yellowBox.addEventListener(MouseEvent.CLICK, changeColor);

function changeColor(e:Event):void {
	trace("CLICKED: e.target.name = "+e.target.name);
	if(e.target.name == "blueBox"){
		Tweener.addTween(this.bigBox, {_color:0x0000FF, time:1, transition:"linear"});
		trace("changing color to blue");
	} else if(e.target.name == "redBox") {
		Tweener.addTween(this.bigBox, {_color:0xFF0000, time:1, transition:"linear"});
		trace("changing color to blue");		
	} else if(e.target.name == "yellowBox") {
		Tweener.addTween(this.bigBox, {_color:0xFFFF00, time:1, transition:"linear"});
		trace("changing color to blue");			
	} else {
		trace("this shouldn't be possible");
	}
}
can I somehow change the example above so it passes the color to use to the function as a parameter instead?

thanks
felisan
-----------------------------------------
http://www.felix-sanchez.dk
postbit arrow 14 comments | 18438 views postbit arrow Reply: with Quote   
Registered User
felisan is offline
seperator
Posts: 236
2005-02-18
Age: 33
felisan lives in Denmark
seperator

Ultrashock Member Comments:
Isocase's Avatar Isocase Isocase is offline Isocase lives in United States 2008-05-29 #2 Old  
I don't think you can but you only using three colors. What is wrong with keeping it as is and why do you need/want to pass it in as a param?

Side note you can use a switch statement instead of else if's.

ActionScript Code:
  1. blueBox.addEventListener(MouseEvent.CLICK, changeColor);
  2. redBox.addEventListener(MouseEvent.CLICK, changeColor);
  3. yellowBox.addEventListener(MouseEvent.CLICK, changeColor);
  4.  
  5. function changeColor( e:Event ):void
  6. {
  7.     switch( e.target.name )
  8.     {
  9.         case "blueBox":
  10.             trace( "blueBox" );
  11.             Tweener.addTween(this.bigBox, {_color:0x0000FF, time:1, transition:"linear"});
  12.         break;
  13.        
  14.         case "redBox":
  15.             Tweener.addTween(this.bigBox, {_color:0xFF0000, time:1, transition:"linear"});
  16.         break;
  17.        
  18.         case "yellowBox":
  19.             Tweener.addTween(this.bigBox, {_color:0xFFFF00, time:1, transition:"linear"});
  20.         break;
  21.     }
  22. }
Reply With Quote  
Armen's Avatar Armen Armen is offline Armen lives in Canada 2008-05-29 #3 Old  
You can add property to the boxes like: blueBox._color=0x0000FF;
and after just change the color based on event target _color property like:
Code:
blueBox._color=  0x0000FF; 
redBox._color=0xFF0000;
yellowBox._color=0xFFFF00;
blueBox.addEventListener(MouseEvent.CLICK, changeColor);
redBox.addEventListener(MouseEvent.CLICK, changeColor);
yellowBox.addEventListener(MouseEvent.CLICK, changeColor);

function changeColor( e:Event ):void
{
  Tweener.addTween(this.bigBox, {_color:e.target._color, time:1, transition:"linear"});
 }
should work.
Reply With Quote  
Codemonkey's Avatar Codemonkey Codemonkey is offline Super Moderator Codemonkey lives in Netherlands 2008-05-29 #4 Old  
Both are good. Here's yet another way. It's not better, just... different

ActionScript Code:
  1. blueBox.addEventListener(MouseEvent.CLICK, function(e:Event) { changeColor(0x0000FF); });
  2. redBox.addEventListener(MouseEvent.CLICK, function(e:Event) { changeColor(0xFF0000); });
  3. yellowBox.addEventListener(MouseEvent.CLICK, function(e:Event) { changeColor(0xFFFF00); });
  4.  
  5. function changeColor(color:Number):void {
  6.   Tweener.addTween(this.bigBox, {_color:color, time:1, transition:"linear"});
  7.  }
Reply With Quote  
felisan felisan is offline felisan lives in Denmark 2008-05-30 #5 Old  
Last edited by felisan : 2008-08-28 at 10:56.
thanks for helping, all 3 of you.
this will surely come in handy many times in the future.

by the way, I've blogged the issue here:
http://www.campjohn.dk/wp/?p=114
Reply With Quote  
Nutrox's Avatar Nutrox Nutrox is online now Super Moderator Nutrox lives in United Kingdom 17 Creative Assets 2008-05-30 #6 Old  
Quote: Originally Posted by Codemonkey View Post
Both are good. Here's yet another way. It's not better, just... different

ActionScript Code:
  1. blueBox.addEventListener(MouseEvent.CLICK, function(e:Event) { changeColor(0x0000FF); });
  2. redBox.addEventListener(MouseEvent.CLICK, function(e:Event) { changeColor(0xFF0000); });
  3. yellowBox.addEventListener(MouseEvent.CLICK, function(e:Event) { changeColor(0xFFFF00); });
  4.  
  5. function changeColor(color:Number):void {
  6.   Tweener.addTween(this.bigBox, {_color:color, time:1, transition:"linear"});
  7.  }

Sorry mate, I have to pick you up on that one.

You should never use inline/anonymous functions for event listeners because (a) you can never remove those listeners again, and (b) the objects you are listening to will never be garbage collected even if you declare the listener as a weak reference.

Armen's solution is the best one to use here, especially if the objects are extending a class with a "color" property defined.

Reply With Quote  
Codemonkey's Avatar Codemonkey Codemonkey is offline Super Moderator Codemonkey lives in Netherlands 2008-05-30 #7 Old  
My my

You're right, but...

It depends on the context in which you define and use closures. In this specific case you might argue you would never want to remove those listeners and not even need the objects-being-listened-to garbage collected, though you wouldn't decide on something like that lightly.

It takes some experience to know when you can or shouldn't use closures, but closures are a topic on their own... not that I'm saying this is a particular wise approach, it isn't really from an application architectural point of view, but like I said... it's not better, just different. Personally, I would go for Armen's solution.

Quote: Originally Posted by Nutrox View Post
and (b) the objects you are listening to will never be garbage collected even if you declare the listener as a weak reference.
How is that? If you declare the listener as weak, the listener is garbage collected the first sweep, as the listener has no strong references to it. How would that cause the broadcasting object to never be garbage collected?
Reply With Quote  
Nutrox's Avatar Nutrox Nutrox is online now Super Moderator Nutrox lives in United Kingdom 17 Creative Assets 2008-05-30 #8 Old  
I'm pretty sure weak references don't work with closures. I remember running a few tests and posting the results in a thread around here somewhere, but I can't find it at the moment. I will have another look for it this evening when I have a bit more free time.
Reply With Quote  
asannov asannov is offline asannov lives in Turkey 2009-08-02 #9 Old  
Last edited by asannov : 2009-08-17 at 06:49.
Code:
var boxes:Array = [blueBox, redBox, yellowBox, blackBox, whiteBox, ... bla bla bla];
var colors:Array = [0x0000FF, 0xFF0000, 0xFFFF00, 0x000000, 0xFFFFFF, ... bla bla bla];

for (var i:Number = 0; i<boxes.length; i++){
    boxes[i].addEventListener(MouseEvent.CLICK, changeColor);
}
function changeColor(e:MouseEvent):void{
    Tweener.addTween(this.bigBox, {_color:colors[boxes.indexOf(e.currentTarget)], time:1, transition:"linear"});
 }
just signed up to post this, but i think this is the best way if there are more than three boxes and colors
Reply With Quote  
thatsasif thatsasif is offline thatsasif lives in India Creative Assets 2009-08-03 #10 Old  
Code:
blueBox.addEventListener(MouseEvent.CLICK,function(e:MouseEvent){changeColor(e, 0x0000FF)},false, 0, true);
redBox.addEventListener(MouseEvent.CLICK,function(e:MouseEvent){changeColor(e, 0xFF0000)},false, 0, true);
yellowBox.addEventListener(MouseEvent.CLICK,function(e:MouseEvent){changeColor(e, 0xFFFF00)},false, 0, true);


function changeColor(e:MouseEvent, color:uint) {
	Tweener.addTween(e.target, {_color:color, time:1, transition:"linear"});
}
Reply With Quote  
felisan felisan is offline felisan lives in Denmark 2009-08-04 #11 Old  
@thatsasif

isn't your example almost the same as the example Codemonkey posted at #4 and Nutrox argumented against at #6 ?

thanks
Reply With Quote  
Isocase's Avatar Isocase Isocase is offline Isocase lives in United States 2009-08-04 #12 Old  
@thatsasif

That code you posted just looks filthy!!!!

I agree with Nutrox in not using inline/anonymous functions but if you feel you want to go that route then go ahead.
Reply With Quote  
Keslen Keslen is offline Keslen lives in Canada 2009-08-05 #13 Old  
Quote: Originally Posted by Nutrox View Post
Sorry mate, I have to pick you up on that one.

You should never use inline/anonymous functions for event listeners because (a) you can never remove those listeners again, and (b) the objects you are listening to will never be garbage collected even if you declare the listener as a weak reference.

Armen's solution is the best one to use here, especially if the objects are extending a class with a "color" property defined.

Hm, this is a problem I've been wresting with lately. I've got a lot of data flying around and due to the versatility of it, including a colour option wouldn't be feasible for me. I do, however, understand why anonymous functions are a terrible idea all around, but I wonder if the following would be an acceptable compromise, especially considering the fact that it could scale fairly easily as you add more colours? Keep in mind that response time is exceedingly important to me while memory storage is much more readily available.

ActionScript Code:
  1. var functionCalls:Array = new Array();
  2. functionCalls[0] = function(e:Event) { changeColor(0x0000FF); }
  3. functionCalls[1] = function(e:Event) { changeColor(0xFF0000); }
  4. functionCalls[2] = function(e:Event) { changeColor(0xFFFF00); }
  5.  
  6. blueBox.addEventListener(MouseEvent.CLICK, functionCalls[0]);
  7. redBox.addEventListener(MouseEvent.CLICK, functionCalls[1]);
  8. yellowBox.addEventListener(MouseEvent.CLICK, functionCalls[2]);
  9.  
  10. function changeColor(color:Number):void {
  11.   Tweener.addTween(this.bigBox, {_color:color, time:1, transition:"linear"});
  12.  }
Reply With Quote  
Nutrox's Avatar Nutrox Nutrox is online now Super Moderator Nutrox lives in United Kingdom 17 Creative Assets 2009-08-05 #14 Old  
That would be a better way to do things I believe, I can't see any obvious problems with it. The functions are still anonymous but you aren't losing reference to them, they look more like regular callbacks now.
Reply With Quote  
Isocase's Avatar Isocase Isocase is offline Isocase lives in United States 2009-08-05 #15 Old  
What about the below?
Code:
blueBox.addEventListener(MouseEvent.CLICK, boxClickHandler);
redBox.addEventListener(MouseEvent.CLICK, boxClickHandler);
yellowBox.addEventListener(MouseEvent.CLICK, boxClickHandler);

function boxClickHandler(event:MouseEvent):void {
	switch (event.target) {
		case blueBox:
			changeColor(0x0000FF);
			break;
		case redBox:
			changeColor(0xFF0000);
			break;
		case yellowBox:
			changeColor(0xFFFF00);
			break;
	}
}

function changeColor(color:Number):void {
	Tweener.addTween(this.bigBox, {_color:color, time:1, transition:"linear"});
}
Reply With Quote  
Thread Tools
Display Modes Rate This Thread
Rate This Thread: