создать один addEventListener для всех элементов массива в ActionScript - PullRequest
2 голосов
/ 07 августа 2011

У меня есть массив видеороликов, представляющих кнопки, по которым пользователь может нажимать на них, поэтому мне нужно использовать функцию addEventListener, чтобы можно было обработать щелчок.

Я могу использовать цикл и создать en addEventListener для каждого элемента, у меня будет 26 элементов в массиве, но я хочу попробовать другое решение, используя только один addEventListener, и применить его к массиву вместо элементов.

Я хочу знать, как распознать, какая кнопка была нажата, я имею в виду ее индекс в массиве.

Спасибо.

Ответы [ 6 ]

6 голосов
/ 07 августа 2011

Вероятно, сейчас самое время узнать о пузырях событий.Вы можете просто добавить одного слушателя к общему родителю всех ваших кнопок

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 вернет дочерние активыкнопки.

0 голосов
/ 07 августа 2011

Вы можете создать свой собственный векторный класс для 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

Вы можете проверить ответ Стигглерса на вопрос Actionscript 3.0 Лучший вариант для создания подкласса Vector Class (Flash Player 10) для получения более подробной информации.

0 голосов
/ 07 августа 2011

Создайте класс для ваших кнопок и добавьте прослушиватель событий в класс. Таким образом, вам даже не придется циклически просматривать видеоклипы, так как метод будет частью класса

0 голосов
/ 07 августа 2011

Вы не можете выйти из циклов напрямую - какой-то цикл должен будет где-то применяться, но вы можете выйти из циклов косвенно - вы можете позволить циклу ВМ для вас.Вы должны взглянуть на 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.indexOf вместе с event.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 ) );
}

Но я не могу быть уверен, не зная больше о вашем конкретном случае использования.

0 голосов
/ 07 августа 2011

Вы не можете назначить прослушиватель событий массиву.

Я думаю, что вы делаете, применяете разные функции прослушивателя событий для каждого клипа в массиве.из клипов вы можете добавить тот же прослушиватель событий:

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
}
0 голосов
/ 07 августа 2011

Добавьте его в мувиклип. Добавление прослушивателя событий в массив не имеет большого смысла. Вы в основном говорите: «Привет, массив, дайте мне знать, когда что-то в вас изменится», а Array не является подклассом EventDispatcher, так что это не нужно. Но в любом случае вы не хотите знать о массиве, вы хотите знать о мувиклипе, поэтому логичным будет сделать цикл и добавить его в мувиклип.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...