Ronnie Goodrich
Ronnie Goodrich

Reputation: 41

Adding event listeners dynamically

Suppose I want to create a single button. This should be easy enough - just create a square, addChild to add it to the screen and an event listener for mouse.CLICK event

add_btn_listeners():void
 {

   btn[0].addEventListener(MouseEvent.CLICK, btn_clc1);
 }
public function btn_clc1(event:Event):void
 {
   action1();
 }

Suppose though that you wanted to create twenty buttons. You would then need twenty functions similar to the above btn_clc1 function with an event listener for the appropriate click.

But suppose you wanted the action to very slightly such as by index. For example, btn[0] calling action1, btn[1] calling action2, etc. in the same listener btn_clc1 listener.

A very common example of this would be mouse rollover. On rollover to highlight a square for instance, increasing the alpha layer to highlight a menu selection. The highlighted layer would depend on the index, something like: btn[index].alpha = .9;

Is there a way to reduce the number of event listeners, or code more optimally in cases like this? Most of the example's I've seen seem kind of shallow for larger cases.

Upvotes: 0

Views: 142

Answers (2)

Marty
Marty

Reputation: 39456

This is exactly the type of problem that object oriented programming is designed to solve. Just create a class with the event handlers in it - then you can create as many of them as you like.

Class example:

public class MyButton extends Sprite
{
    public function MyButton()
    {
        graphics.beginFill(0);
        graphics.drawRect(0, 0, 50, 30);
        graphics.endFill();

        addEventListener(MouseEvent.CLICK, _mouse);
        addEventListener(MouseEvent.ROLL_OVER, _mouse);
        addEventListener(MouseEvent.ROLL_OUT, _mouse);
    }

    private function _mouse(e:MouseEvent):void
    {
        switch(e.type)
        {
            case MouseEvent.CLICK:
                trace("click");
            break;

            case MouseEvent.ROLL_OVER:
                alpha = 0.9;
            break;

            case MouseEvent.ROLL_OUT:
                alpha = 1;
            break;
        }
    }
}

Then you can create them like so:

for(var i:int = 0; i < 5; i++)
{
    var btn:MyButton = new MyButton();

    btn.x = i * 60;
    addChild(btn);
}

Upvotes: 1

mitim
mitim

Reputation: 3201

One thing you can do is within the event object in the event handler, there is a 'target' property. This refers to the object that dispatched the event. You can cast it back in to whatever you assigned the event listener to and access it, or can just use a loop/if block to compare to figure out which button it was.

import flash.display.Sprite;

var aButton:Sprite = new Sprite();

function clicked(inputEvent:MouseEvent):void {
    var theButton:Sprite = (Sprite) (inputEvent.target);
    trace(theButton); // traces out the sprite

    // can compare
    trace(theButton == aButton); // traces out true

    // if the had any (custom) properties, you could also access them, such as:
    trace(theButton.visible);
}
aButton.addEventListener(MouseEvent.CLICK, clicked, false, 0, true);

Upvotes: 1

Related Questions