Показать сообщение отдельно
Старый 27.10.2006, 12:54
MerlinTwi вне форума Посмотреть профиль Отправить личное сообщение для MerlinTwi Посетить домашнюю страницу MerlinTwi Найти все сообщения от MerlinTwi
  № 71  
Ответить с цитированием
MerlinTwi
 
Аватар для MerlinTwi

Регистрация: Oct 2003
Адрес: Москва
Сообщений: 328
По умолчанию 77. Определение добавления или удаления со Stage

В предыдущем примере показано как определить добавление и удаление объекта от другого отображаемого объекта. Но если с экрана будет удален наш родительский объект, то события 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 при удалении.
__________________
Создатель: Бойцовский клуб | TimeZero | Sky2Fly
Я возьму сам.