В предыдущем примере показано как определить добавление и удаление объекта от другого отображаемого объекта. Но если с экрана будет удален наш родительский объект, то события ADDED/ REMOVED не сработают. Как же отследить реальное добавление или удаление с экрана? Можно воспользоваться классом StageDetection (
com.senocular.events.StageDetection)
Код:
package com.senocular.events {
import flash.display.DisplayObject;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.utils.Dictionary;
/**
* StageDetection
* Позволяет DisplayObject реагировать на добавление и удаление со stage
*
* Использовать в конструкторе
* var stageDetect:StageDetection = new StageDetection(this);
* stageDetect.addEventListener(StageDetection.ADDED_TO_STAGE, addedToStage);
* stageDetect.addEventListener(StageDetection.REMOVED_FROM_STAGE, removedFromStage);
*/
public class StageDetection extends EventDispatcher {
protected var target:DisplayObject;
protected var parents:Dictionary;
protected var detect:String;
public static const ADDED_TO_STAGE:String = "addedToStage";
public static const REMOVED_FROM_STAGE:String = "removedFromStage";
/**
* Конструктор
*/
public function StageDetection(targetObject:DisplayObject) {
target = targetObject;
// Определяем за чем нужно следить, за добавлением или удалением
detect = (target.stage == null) ? Event.ADDED : Event.REMOVED;
// Обновляем слушателей у родителей
updateListeners();
}
/**
* Обновляет слушателей событий ADDED и REMOVED
*/
protected function updateListeners(newDetect:String = null):void {
// Очищаем старые listeners у родителей
if (parents) {
for (var key:Object in parents) {
key.removeEventListener(detect, stageCheck, false);
}
}
// Запомним на какие события подписываемся
if (newDetect) detect = newDetect;
// Прописывает слушателей этого события у родителей
parents = new Dictionary(true);
var parent:DisplayObject = target;
while (parent) {
parent.addEventListener(detect, stageCheck, false, 0, true);
parents[parent] = true;
parent = parent.parent;
}
}
/**
* В обработчике ADDED и REMOVED проверяем наличие stage
*/
protected function stageCheck(evt:Event):void {
// Реагируем только на оригинальный источник события
if (evt.target != evt.currentTarget) return;
// evt.type или ADDED или REMOVED
switch(evt.type) {
// Кого-то из родителей добавили к другому объекту
case Event.ADDED:
// stage доступен, значит нас добавили на экран
if (target.stage != null) {
// Рассылаем событие и обновляем listeners
dispatchEvent(new Event(ADDED_TO_STAGE));
updateListeners(Event.REMOVED);
// stage недоступен, значит просто добавили к другому объекту
} else {
// Список родителей изменился, значит обновим listeners
updateListeners();
}
break;
// Родителя удалили со stage
case Event.REMOVED:
// Рассылаем событие и обновляем listeners
dispatchEvent(new Event(REMOVED_FROM_STAGE));
updateListeners(Event.ADDED);
break;
}
}
}
}
MerlinTwi: На данный момент этот класс стоит рассматривать только в ознакомительных целях, как можно красиво реализовать решение поставленной задачи. Практической пользы нет, т.к. с очередным обновлением Flash плеера были добавлены события ADDED_TO_STAGE и REMOVED_FROM_STAGE позволяющие DisplayObject 'у проверять доступность stage. Событие ADDED_TO_STAGE отправляется DisplayObject 'у когда он один или дерево объектов с ним добавляются на сцену, REMOVED_FROM_STAGE при удалении.