Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   События остаются после их удаления (http://www.flasher.ru/forum/showthread.php?t=185516)

Wolsh 15.10.2012 11:46

Господа, немедленно сбросьте пылкость речей. На форуме запрещено переходить на личности.

Frost47rus, не надо придумывать свои правила подсчета. Событие одно — MouseEvent.CLICK. Оно не бывает "внутренним" или "внешним". Эти определения можно отнести к слушателям, да. Слушателей может быть сколько угодно, даже у "здравомыслящего" разработчика. Вот чего бы мне никогда не пришло в голову, так это диспатчить "как правило такое же" событие из собственного обработчика кнопки. "Как правило" кнопка подписывается на клик по себе исключительно для собственных целей, "как правило" — отображения своей реакции на клик: анимации или другого визуального эффекта. Можно, конечно, завести для этих целей специальный интерактивный объект, и слушать внутри кнопки клик по этому объекту (хитАреа). Но далеко не всегда это целесообразно, поскольку описанной ТС проблемы вообще-то никогда не существовало, и городить лишние механизмы в кнопке никакого смысла нет (если конечно нет нужды в назначении в качестве хитАреа какого-то внешнего объекта). Так что два Слушателя на одно событие Клик — это вполне нормальная ситуация и не надо делать вид, что собственная подписка кнопки "не считается".

Frost47rus 15.10.2012 11:53

я всё-таки исходил из мнения, что кнопка как объект и её hitArea как объект - два разных объекта.
то, что вся кнопка целиком может быть как одна hitArea - и вся подписана на событие внутри себя же - лишь частный случай.
зачастую приходится работать с кнопками, которые художники рисуют в фш. и кнопка сама по себе будет png с прозрачностью.
и если заглянуть в тот же широкоизвестный Interactive PNG - найдём там то же самое - отрисовку hitArea, но попиксельно.

Wolsh, а насчёт диспетча - я не понял, что имеется в виду тут: "так это диспатчить "как правило такое же" событие из собственного обработчика кнопки"?
А какое же тогда? От самой hitArea передавать тот же? Это будет эвент не от кнопки в таком случае, а от её части и доступа к полям нужного event - получено не будет.

Wolsh 15.10.2012 12:19

Непонятно, зачем писать диспатч клика, если он происходит "автоматически", то есть это стандартное поведение InteractiveObject, наследником которого является Ваша кнопка. Проще говоря, она ИТАК продиспатчит клик, зачем это дублировать дополнительно? Чтобы было два диспатча?

Добавлено через 3 минуты
Interactive PNG — да, хороший пример внутренней подписки на все возможные мышиные события с целью их проанализировать и решить, диспатчить клик "наружу" или нет. Но тоже весьма частный случай))

Frost47rus 15.10.2012 13:18

Wolsh, прочтите, пожалуйста, код, который я написал на первой странице темы.
Этот эвент не дублируется. Эвент "внутри" - относится к hitArea кнопки, т.е. event.target - [object MovieClip]. Новый же эвент - он для внешних слушателей и относится к экземпляру [object MyButton].
Вы, видимо, поторопились с выводами.

in4core 15.10.2012 13:47

Frost47rus
Код AS3:

if (layout.getChildByName('hit') == null)
dispatchEvent(new MouseEvent(MouseEvent.CLICK));
(_enabled == true) ? turnOn() : turnOff();

Мне не о чем с Вами говорить далее.

Wolsh, Silin - ну тогда давай те я приведу полный код, своей сборки и мы вместе выясним где же я косячу.

Вот код любой кнопки

Код AS3:

package pro.clonez.slots 
{
        import flash.display.MovieClip;
        import flash.events.MouseEvent;
        import flash.text.TextField;
 
        /**
        * ...
        * @author in4core lab
        */

        public class EvaluteButton extends MovieClip
        {
                public var tf:TextField;
                private var _isEnabled:Boolean = true;
 
                public function EvaluteButton()
                {
                        this.mouseChildren = false;
                        this.buttonMode = true;
                        this.tabChildren = false;
                        this.tabEnabled = false;
 
                        this.addEventListener(MouseEvent.MOUSE_OVER , this.over);
                        this.addEventListener(MouseEvent.MOUSE_OUT , this.out);
                        this.addEventListener(MouseEvent.CLICK , this.release);
                        this.addEventListener(MouseEvent.MOUSE_DOWN , this.down);
                }
 
                public function down(e:MouseEvent):void
                {
                        this.gotoAndStop('down');
                }
 
                public function release(e:MouseEvent):void
                {
                        if (stage)
                        {
                                if (this.hitTestPoint(stage.mouseX , stage.mouseY))
                                {
                                        this.over(e);
                                }
                                else
                                {
                                        this.out(e);
                                }
                        }
 
                }
 
                public function out(e:MouseEvent):void
                {
                        this.gotoAndStop('simple');
                }
 
                public function over(e:MouseEvent):void
                {
                        this.gotoAndStop('over');
                }
 
                public function disable():void
                {
                        this.removeEventListener(MouseEvent.CLICK , this.release);
                        this.removeEventListener(MouseEvent.MOUSE_OVER , this.over);
                        this.removeEventListener(MouseEvent.MOUSE_OUT , this.out);
                        this.removeEventListener(MouseEvent.MOUSE_DOWN , this.down);
                        this.mouseEnabled = false;
                        this.buttonMode = false;
                        this.gotoAndStop("inactive");
                        this._isEnabled = false;
                }
 
                public function enable():void
                {
                        this.addEventListener(MouseEvent.MOUSE_OVER , this.over);
                        this.addEventListener(MouseEvent.MOUSE_OUT , this.out);
                        this.addEventListener(MouseEvent.CLICK , this.release);
                        this.addEventListener(MouseEvent.MOUSE_DOWN , this.down);
                        this.mouseEnabled = true;
                        this.out(null);
                        this.buttonMode = true;
                        this._isEnabled = true;
                }
 
                public function get isEnabled():Boolean
                {
                        return _isEnabled;
                }
 
        }
 
}

Как мы видим при disabled - слушатели снимаются четко.

Имеем 2 кнопки. - и + . При определенных условиях нажатия 1й или второй, одна из них блокируется, либо не блокируется ни одна. Смотрим

Код AS3:

this._hud.mline.addEventListener(MouseEvent.CLICK , minusLine);
this._hud.pline.addEventListener(MouseEvent.CLICK , plusLine);

Код AS3:

private function minusLine(e:MouseEvent):void 
                {
                        this.dispatchEvent(new HUDViewEvent(HUDViewEvent.MINUS_LINE));
                }
 
                private function plusLine(e:MouseEvent):void
                {
                        this.dispatchEvent(new HUDViewEvent(HUDViewEvent.PLUS_LINE));
                }

Когда моделька упдейтится начинаем проверочку

Код AS3:

private function updateCurrentLine(e:HUDModelEvents):void 
                {
                        if (this._hudModel.currentLine === this._hudModel.numLines)
                        {
                                //this._hud.pline.removeEventListener(MouseEvent.CLICK , plusLine);
                                this._hud.pline.disable();
                        }
                        else if (this._hudModel.currentLine === 1)
                        {
                                //this._hud.mline.removeEventListener(MouseEvent.CLICK , minusLine);
                                this._hud.mline.disable();
                        }
                        else
                        {
                                if (!this._hud.pline.isEnabled)
                                {
                                        this._hud.pline.enable();
                                        //this._hud.pline.addEventListener(MouseEvent.CLICK , plusLine);
                                }
                                if (!this._hud.mline.isEnabled)
                                {
                                        this._hud.mline.enable();
                                        //this._hud.mline.addEventListener(MouseEvent.CLICK , minusLine);
                                }
                        }
                }

Выложил полный код, чтобы было видно где может быть косяк.
Видно - что кнопка подписана на 2 клика, первый происходит сразу же, второй(логика) по событию от модельки . Я специально унес в комментарии удаление второго слушателя, так было изначально - и при таком подходе мы получали следующее - over , down , disable (!!! сняли клик) , release , over . При подходе 2 ( убрав комментарии , тоесть снимая и второго слушателя ) - over , down , disable ! - все верно. Где же я косячу?

silin 15.10.2012 14:20

in4core, вот ты пишешь
Цитата:

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

in4core 15.10.2012 14:34

silin - ну вроде как пример довольно минималистичный. Тут даже достраивать ничего не надо. Класс кнопки есть ( показал ) , а кнопки допустим подпишем на
Код AS3:

private function updateCurrentLine(e:HUDModelEvents):void

- вот и готов пример. Видим код кнокпи и код *внешнего* слушателя

Wolsh 15.10.2012 14:54

Frost47rus, Ваш клипопреобразователь имеет какое-то отношение к данной теме?
in4core, Вам надо выйти из телепатического транса и почувствовать, как мыслят обычные флэш-обыватели.
Хотя бы покажите место, откуда Вы получаете свой изумительный трейс. По какому конкретно событию он происходит. Что Вы делаете с кнопками, отчет. А вот в коде Модели Вам бы самому покопаться — боюсь другим будет лень, даже догадываясь, что причина где-то там..

Добавлено через 2 минуты
От Ваших thisов уже глаза щиплет..

in4core 15.10.2012 15:08

Wolsh - ненавистник зисов? ) А мне кажется это лучший код-стайл.
Соберу пожалуй седня пример для запуска.

Frost47rus 15.10.2012 15:24

Код AS3:

private var _isEnabled:Boolean = true;

приватные переменные обозначаются в конструкторе.

Код AS3:

private var _isEnabled:Boolean = true;
 
и тут же
 
public function get isEnabled():Boolean {
 return _isEnabled;
}

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

Код AS3:

this.tabChildren = false;
this.tabEnabled = false;

поясните, зачем?

Код AS3:

public function release(e:MouseEvent):void {
 if (stage) {
.....

совершенно не ясна проверка на наличие стейджа. если его не было бы - не было бы события.

Код AS3:

if (this.hitTestPoint(stage.mouseX , stage.mouseY)) 
                                {
                                        this.over(e);
                                }
                                else
                                {
                                        this.out(e);
                                }

это типа, если нажал и увел мышку в другую область и отжал?
это не надо проверять - такое поведение пользователя не приведёт к событию MouseEvent.CLICK - проверьте сами.

Код AS3:

public function enable():void
                {
                        this.addEventListener(MouseEvent.MOUSE_OVER , this.over);
                        this.addEventListener(MouseEvent.MOUSE_OUT , this.out);
                        this.addEventListener(MouseEvent.CLICK , this.release);
                        this.addEventListener(MouseEvent.MOUSE_DOWN , this.down);
                        this.mouseEnabled = true;
                        this.out(null);

последняя строка. зачем?
а если активация будет во время пребывания мыши над кнопкой? получите кашу.

Код AS3:

private function minusLine(e:MouseEvent):void

мышиный эвент хэндлер назван совсем как не хэндлер. вы сами в своём коде не путаетесь? вы - ладно, другим его читать - давать нельзя.

Код AS3:

if (this._hudModel.currentLine === this._hudModel.numLines)
                        {
                                //this._hud.pline.removeEventListener(MouseEvent.CLICK , plusLine);
                                this._hud.pline.disable();
                        }
                        else if (this._hudModel.currentLine === 1)
                        {
                                //this._hud.mline.removeEventListener(MouseEvent.CLICK , minusLine);
                                this._hud.mline.disable();
                        } else

вам самому понятна логика в этом дереве?

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


Код AS3:

if (layout.getChildByName('hit') == null)
dispatchEvent(new MouseEvent(MouseEvent.CLICK));
(_enabled == true) ? turnOn() : turnOff();

а тут - разберитесь для начала(вам, как я понял, это не по силам), а потом критикуйте ;)

Добавлено через 3 минуты
Цитата:

Сообщение от Wolsh (Сообщение 1099976)
Frost47rus, Ваш клипопреобразователь имеет какое-то отношение к данной теме?

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


Часовой пояс GMT +4, время: 15:53.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.