1

I am creating a line of Sprite elements. Every sprite element has different job, when it is clicked. How can I make the function inside the addEventListener to know which button was clicked?

In this case, the traced value of i when it is cliicked is always 6. Which is wrong, because 6 is only the last element of the array. What about the rest of them, the beginning?

for (var i:int = 0; i < 6; i++) {
    var barPart:Sprite = new Sprite();
    barPart.x = i * (30);
    barPart.y = 0;
    barPart.graphics.beginFill(0x000000, 0.2);
    barPart.graphics.drawRect(0, 0, 10, 10);
    barPart.graphics.endFill();

    barPart.addEventListener(MouseEvent.CLICK, function(_event:MouseEvent):void {
         trace(i);
    });
}
Ágota Horváth
  • 1,353
  • 3
  • 13
  • 20
  • 1
    Take a look: http://stackoverflow.com/questions/19739366/create-a-set-of-anonymous-functions-with-parameters-defined-at-definiton-time/19739427#19739427 – Ivan Chernykh Nov 10 '13 at 08:54

3 Answers3

3

When the application is build and the listeners are added, the loop has already executed, so the index "i" will always be six by the time the user ends up clicking the button. To distinguish between the different items, use their "name" property (prop of DisplayObject) like shown ... Try not to have listener function as a method closure in a loop, instead do this:

for (...)
{
    ... code
    barPart.name = "barPart-" +i;
    barPart.addEventListener(MouseEvent.CLICK, barPart_clickHandler);
}

and implement the function (event handler separately) like:

private function barPart_clickHandler(e:MouseEvent):void
{
    // the event's target will let you know who dispatched the function
    var name:String = Sprite(e.currentTarget).name;
    name            = name.replace("barpart-", "");
    switch(name)
    {
        case '0':
            // your code
            break;
        .
        .
    }
}
0

@Shally Virk - My mistake. I was thinking of MovieClip which is a dynamic object so it allows adding arbitrary fields. You are right, there are lots of ways to get around this problem, but your suggestion works fine.

null
  • 1,187
  • 1
  • 8
  • 20
0

While the cause is not clear to me, the answer is a little more simple,

The events are registered correctly, but flash takes the last computed value. Knowing that we can work around.
The work around can either do like Shally Virk wrote, but that tends to get confusing on bigger scale. So we want something more general and simple.
Now here are the steps taking this in mind:

1. We know sprite are not dynamic, so we make class to extend spirte and make it dynamic. Since the class has basically 0 code, the only difference being the dynamic , the amount of memory added is small
2. Having the class here's the code:

for (var i:int = 0; i < 6; i++) {
    var barPart:CustomSprite = new CustomSprite();
    barPart.x = i * (30);
    barPart.y = 0;
    barPart.graphics.beginFill(0x000000, 0.2);
    barPart.graphics.drawRect(0, 0, 10, 10);
    barPart.graphics.endFill();
    barPart.i = i;

    barPart.addEventListener(MouseEvent.CLICK, function(_event:MouseEvent):void {
         trace(_event.currentTarget.i);
    });
}

:)

Nertan Lucian
  • 362
  • 4
  • 16