Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Словить все элементы через которые bubble'ится эвент (http://www.flasher.ru/forum/showthread.php?t=187206)

AlexLucas 15.11.2012 16:15

Словить все элементы через которые bubble'ится эвент
 
Добрый день.

У меня есть приложение с кучей вложенных элементов, при клике на любой из них. я хочу получить все его паренты, т.е. при клике на элемент, эвент (по идее) проходит через все эти компоненты и до мэйн класса. Это мне нужно для того чтобы проверить если элемент является чайлдом какого-то определённого компонента
Код AS3:

public class MainClass{
...
 
private function init() {
    addEventListener(MouseEvent.CLICK, checkClick);
}
 
private function checkClick(e:MouseEvent) {  // при этом e.target != объект MainClass
                                              // как-то из e достать список всех парентов e.target?
    if( ОдинИзПарентовМоегоЭлемента as НужныйМнеКласс) { ..... }
}
 
}

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

Aquahawk 15.11.2012 16:18

Слушайте в топ левел, смотрите таргет, там будет непосредственно тот на кого кликнули, и по его parent поднимайтесь до себя, там будут все по кому прошёл ивент.

AlexLucas 15.11.2012 16:30

Да да, так и сделал :)
Код AS3:

var obj:* = e.target;
while(true) {                                                                               
                                        if (obj as МойКласс) { canvasTrace('BUBBLED from MODULE');        break;  }
                                        if ( obj == this) { canvasTrace('NO IMODULE PARENT!'); break; }
                                        obj = obj.parent;                                       
                                }


Aquahawk 15.11.2012 17:10

Цитата:

if (obj as МойКласс)
лучше использовать is. Хотя в данном случае и так будет работать. Почитайте разницу между ними.

Korchy 15.11.2012 20:55

Цитата:

Сообщение от AlexLucas (Сообщение 1104553)
Это мне нужно для того чтобы проверить если элемент является чайлдом какого-то определённого компонента

1. Весь стек объектов по которым прошел клик можно получить и без слушателей, просто через getObjectsUnderPoint
2. Проверку, является ли объект чьим-то чайлдом можно сделать через getChildIndex

Aquahawk 15.11.2012 23:18

Цитата:

1. Весь стек объектов по которым прошел клик можно получить и без слушателей, просто через getObjectsUnderPoint
А если ивент клавиатурный или вообще кастомный. Не мышью единой.
Цитата:

Проверку, является ли объект чьим-то чайлдом можно сделать через getChildIndex
Зачем это делать если сам компонент всегда будет в цепочке парентов. А если там 10 уровней вложенности, по всем идти проверять индекс?

Korchy 16.11.2012 12:07

Цитата:

Сообщение от Aquahawk (Сообщение 1104618)
А если ивент клавиатурный или вообще кастомный. Не мышью единой.

Согласен. Но автор привел конкретный пример с мышкой, если только для мышки - сработает.

Цитата:

Сообщение от Aquahawk (Сообщение 1104618)
Зачем это делать если сам компонент всегда будет в цепочке парентов. А если там 10 уровней вложенности, по всем идти проверять индекс?

Так пробегать цепочку по парентам все равно придется. А если не бегать - можно использовать contains.

Aquahawk 16.11.2012 13:11

Цитата:

А если не бегать - можно использовать contains.
С этого места подробнее. Я не знаю что это такое, но индекс сработает только для прямых чаилдов, при вложенности не сработает. С верха искать ребёнка это рекурсивно ходить по всем детям и их детям в поисках объекта. Бежать по парентам это просто пробежать по парентам, в разы меньше операций.

Korchy 16.11.2012 15:32

Цитата:

Сообщение от Aquahawk (Сообщение 1104683)
С этого места подробнее.

Да, индекс наверное здесь действительно не стоит использовать, а contains делает как раз то, о чем писал тс. Возвращает true если объект является чайлдом от вызывающего.
Из хелпа адоба:

Код AS3:

var sprite1:Sprite = new Sprite();
var sprite2:Sprite = new Sprite();
var sprite3:Sprite = new Sprite();
var sprite4:Sprite = new Sprite();
 
sprite1.addChild(sprite2);
sprite2.addChild(sprite3);
 
trace(sprite1.contains(sprite1)); // true
trace(sprite1.contains(sprite2)); // true
trace(sprite1.contains(sprite3)); // true
trace(sprite1.contains(sprite4)); // false


expl 17.11.2012 13:27

Цитата:

if (obj as МойКласс)
Вообще логичнее is МойКласс, но не суть.

Если под требуемый объект нет резона создавать отдельный МойКласс или заставлять реализовывать МойИнтерфейс есть более гибкий способ:
(ну действительно, нужно только узнать тот ли это объект, не плодить же классы/интерфейсы ради этого)

- создаем константу, где удобнее
Код AS3:

public static const MY_OBJECT:String = "myObject";

- вешаем на требуемый объект пустой слушатель (можно вообще любую функцию - она не будет вызываться, можно вообще одну на весь проект создать в отдельном файле "fakeListener.as")
Код AS3:

myObject.addEventListener(MY_OBJECT, fakeListener);
...
function fakeListener(event:Event):void {}

- проверяем, тот ли это объект
Код AS3:

while(true) {                                                                                
                                        if (obj.hasEventListener(MY_OBJECT)) { canvasTrace('BUBBLED from MODULE');        break;  }
                                        if ( obj == this) { canvasTrace('NO IMODULE PARENT!'); break; }
                                        obj = obj.parent;                                       
                                }

Бонус:
Можно проверить, является ли объект ребёнком какого-нибудь "myObject"
Код AS3:

if (child.willTrigger(MY_OBJECT)) {...}



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

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