为actionscript中的所有数组元素创建一个addEventListener

时间:2011-08-07 01:59:38

标签: actionscript-3 actionscript

我有一组动画片段,代表用户可以点击它们的按钮,因此我需要使用addEventListener函数,以便可以处理点击。

我可以使用循环并为每个元素创建en addEventListener,我将在数组中有26个元素,但我想通过仅使用一个addEventListener尝试另一个解决方案并将其应用于数组而不是元素。

我想知道如何识别单击了哪个按钮,我的意思是它在数组中的索引是什么。

感谢。

6 个答案:

答案 0 :(得分:6)

这可能是了解事件冒泡的好时机。您只需将一个侦听器添加到所有按钮的公共父级

即可
buttonContainer.addEventListener(MouseEvent.CLICK, buttonContainerClickHandler);

然后尝试找出点击的内容

private function buttonContainerClickHandler(e:MouseEvent):void 
{
    var targetButton:Sprite = e.target as Sprite;
    //do something with targetButton.
}

要找出单击的按钮,可以使用数组的indexOf方法,并将其传递给targetButton。

您需要做的一件事是确保每个按钮都将mouseChildren设置为false,否则e.target将返回按钮的子资源。

答案 1 :(得分:0)

将其添加到动画片段。向数组添加事件侦听器并没有多大意义。你基本上是在说“嘿数组,让我知道你什么时候改变了”,而Array不是EventDispatcher的子类,所以这是不行的。但无论如何你不想知道数组,你想知道movieclip,所以合乎逻辑的做法是制作循环并将其添加到movieclip。

答案 2 :(得分:0)

您无法将事件侦听器分配给数组。

我认为您正在做的是为数组中的每个剪辑应用不同的事件侦听器函数。

对于每个剪辑,您可以添加相同的事件侦听器:

clips[i].addEventListener(MouseEvent.CLICK, handleClick);

并且handleClick函数类似于:

function handleClick(e:MouseEvent):void {
    trace(clips.indexOf(e.target)) // outputs index the movieclip that was clicked on
}

答案 3 :(得分:0)

你不能直接退出循环 - 某个循环必须在某个地方应用,但是你可以间接地退出循环 - 你可以让VM为你循环。你应该看看Array.forEach

一个简单的应用程序可能是:

// assuming myArr is your array.
myArr.forEach( function(item:*, index:int, array:Array):void
{ 
    item.addEventListener( MouseEvent.CLICK, myClickHandler );
} );

要获取项目的索引,您可能会做一些更复杂的事情:

myArr.forEach( function(item:*, index:int, array:Array):void
{ 
    item.addEventListener( MouseEvent.CLICK, function( event:Event ):void
    {
        trace( "my index is", index );
    } );
} );

我必须建议您只是将数组缓存到侦听器函数可访问的位置,然后使用Array.indexOfevent.currentTarget,但如果您没有找到可接受的,则可以使用forEach这样:

myArr.forEach( function(item:*, index:int, array:Array):void
{ 
    item.addEventListener( MouseEvent.CLICK, function( event:Event ):void
    {
        trace( "my index is", array.indexOf( item ) );
    } );
} );

根据您调用这些方法的频率,单纯使用它可能不会更快:

// probably not best to have this public
protected var myArr:Array = [/* whatever goes in here */]

public function register():void
{
    myArr.forEach( addHandler );
}

protected function addHandler( item:IEventListener, index:int, arr:Array ):void
{
    item.addEventListener( MouseEvent.CLICK, myClickHandler );
}

protected function myClickHandler( event:MouseEvent ):void
{
    trace( event.currentTarget, "is at", myArr.indexOf( event.currentTarget ) );
}

但是,如果不了解您的特定用例,我无法确定。

答案 4 :(得分:0)

为按钮创建一个类,并将事件侦听器添加到类中。这样您甚至不必遍历影片剪辑,因为该方法将成为类

的一部分

答案 5 :(得分:0)

您可以为IEventDispatcher对象创建自己的自定义向量类,该对象具有自定义方法,可以为其所有元素添加事件侦听器。执行此操作的最佳方法是创建一个代理类,该代理类充当Vector.<IEventDispatcher>对象的包装器。我已经创建了一个示例来证明这一点:

package 
{
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.events.IEventDispatcher;

    public class Main extends Sprite 
    {
        private var _eventDispatcherVector:EventDispatcherVector;

        public function Main():void 
        {
            if (stage) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);

        }// end function

        private function init(e:Event = null):void 
        {
            removeEventListener(Event.ADDED_TO_STAGE, init);

            var redCustomButton:CustomButton = new CustomButton("RED", 0xFF0000);
            addChild(redCustomButton);
            var blueCustomButton:CustomButton = new CustomButton("BLUE", 0x00FF00);
            blueCustomButton.x = 100;
            addChild(blueCustomButton);
            var greenCustomButton:CustomButton = new CustomButton("GREEN", 0x0000FF);
            greenCustomButton.x = 200;
            addChild(greenCustomButton);

            _eventDispatcherVector = new EventDispatcherVector(Vector.<IEventDispatcher>([redCustomButton, 
                                                                                          blueCustomButton, 
                                                                                          greenCustomButton]));

            _eventDispatcherVector.addEventListener(MouseEvent.CLICK, onCustomButtonClick);

        }// end function

        private function onCustomButtonClick(e:Event):void
        {
            var customButton:CustomButton = e.target as CustomButton;

            trace("You clicked: " + customButton.name + "\n" +
                  "Its index is: " + _eventDispatcherVector.indexOf(customButton));

        }// end function

    }// end class

}// end package

import flash.utils.Proxy;
import flash.utils.flash_proxy;
import flash.events.IEventDispatcher;

use namespace flash_proxy;

dynamic internal class EventDispatcherVector extends Proxy
{
    private var _eventDispatcherVector:Vector.<IEventDispatcher>;

    public function EventDispatcherVector(eventDispatcherVector:Vector.<IEventDispatcher>)
    {
        _eventDispatcherVector = eventDispatcherVector;

    }// end function

    override flash_proxy function getProperty(name:*):* 
    {
        return _eventDispatcherVector[name];
    }

    override flash_proxy function setProperty(name:*, value:*):void 
    {
        _eventDispatcherVector[name] = value;

    }// end function

    public function indexOf(searchElement:*, fromIndex:*= 0):int
    {
        return _eventDispatcherVector.indexOf(searchElement, fromIndex);

    }// end function

    public function addEventListener(type:String,
                                     listener:Function,
                                     useCapture:Boolean = false,
                                     priority:int = 0, 
                                     useWeakReference:Boolean = false):void 
    {
        for each(var eventDispatcher:IEventDispatcher in _eventDispatcherVector)
        {
            eventDispatcher.addEventListener(type, listener, useCapture, priority, useWeakReference);

        }// end for each

    }// end function

}// end class

import flash.display.Sprite;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;

internal class CustomButton extends Sprite
{
    public function CustomButton(name:String, color:uint)
    {
        graphics.beginFill(color);
        graphics.drawRect(0, 0, 100, 100);
        graphics.endFill();

        var textField:TextField = new TextField();
        textField.autoSize = TextFieldAutoSize.LEFT;
        textField.text = name;
        textField.mouseEnabled = false; 
        textField.x = (100 / 2) - (textField.width / 2);
        textField.y = (100 / 2) - (textField.height / 2);
        addChild(textField);

        this.name = name;

    }// end function

}// end class

点击CustomButton对象的输出如下:

  

您点击了:红色   其指数为:0
  你点击了:蓝色
  其指数为:1   你点击了:绿色   其指数为:2

有关详细信息,请查看Stigglers对问题Actionscript 3.0 Best Option for Subclassing Vector Class (Flash Player 10)的回答。