Обход списка отображения

Flash Player 9 и более поздних версий, Adobe AIR 1.0 и более поздних версий

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

Класс DisplayObjectContainer включает свойства и методы для обхода списка отображения с помощью списков дочерних объектов с контейнерами экранных объектов. Например, рассмотрим следующий код, который добавляет два экранных объекта (title и pict) в объект container (который относится к классу Sprite, являющемуся расширением класса DisplayObjectContainer):

var container:Sprite = new Sprite(); 
var title:TextField = new TextField(); 
title.text = "Hello"; 
var pict:Loader = new Loader(); 
var url:URLRequest = new URLRequest("banana.jpg"); 
pict.load(url); 
pict.name = "banana loader"; 
container.addChild(title); 
container.addChild(pict);

Метод getChildAt() возвращает дочерний объект списка отображения, который находится на определенной позиции указателя:

trace(container.getChildAt(0) is TextField); // true

Доступ к дочерним объектам может также осуществляться по имени. Каждый экранный объект обладает свойством имени, и если его не присвоить, Flash Player или AIR присваивает значение по умолчанию (например, "instance1"). На примере следующего кода демонстрируется применение метода getChildByName() для доступа к дочернему экранному объекту с именем "banana loader":

trace(container.getChildByName("banana loader") is Loader); // true

Использование метода getChildByName(), в отличие от метода getChildAt(), может привести к снижению производительности.

Так как контейнер экранного объекта может содержать другие контейнеры экранных объектов в качестве дочерних объектов в своем списке отображения, весь список отображения приложения можно обойти как дерево. Например, в указанном ранее фрагменте кода после завершения операции загрузки объекта pict Loader объект pict будет иметь один дочерний экранный объект, в качестве которого выступает загруженное растровое изображение. Чтобы вызвать этот экранный объект растрового изображения, можно написать pict.getChildAt(0). Кроме того, можно ввести container.getChildAt(0).getChildAt(0) (так как container.getChildAt(0) == pict).

Следующая функция приводит к выводу с отступом результата выполнения метода trace(), относящегося к списку отображения из контейнера экранного объекта:

function traceDisplayList(container:DisplayObjectContainer,                                                indentString:String = ""):void 
{ 
    var child:DisplayObject; 
    for (var i:uint=0; i < container.numChildren; i++) 
    { 
        child = container.getChildAt(i); 
        trace(indentString, child, child.name);  
        if (container.getChildAt(i) is DisplayObjectContainer) 
        { 
            traceDisplayList(DisplayObjectContainer(child), indentString + "    ") 
        } 
    } 
}

Adobe Flex

Если вы пользуетесь программой Flex, вы должны знать, что в ней определяются многие классы экранных объектов, и эти классы переопределяют методы доступа к списку отображения для класса DisplayObjectContainer. Например, класс Container из пакета mx.core переопределяет метод addChild() и другие методы класса DisplayObjectContainer (расширением которого является класс Container). В случае метода addChild() этот класс переопределяет его таким образом, что вы не можете добавить все типы экранных объектов в экземпляр контейнера Container во Flex. Переопределенный метод в данном случае требует, чтобы добавляемый дочерний объект относился к типу объекта mx.core.UIComponent.