以下是利用 AS3 Proxy Class 简化 DisplayObject Tree 操作
AS3 DisplayObjectProxy Class:
/*//
AS3 DisplayObjectProxy Class, version 0.0.1
(c) 2007 Shih, Wei-Lung <weilung_shih@hotmail.com>
AS3 DisplayObjectProxy Class is freely distributable
under the terms of an GNU license.
For details, see the Prototype web site: http://ticore.blogspot.com/
//*/
package {
import flash.display.*;
import flash.utils.*;
public dynamic class DisplayObjectProxy extends Proxy {
protected var _target_:DisplayObject;
protected var _keys_:Array;
protected var _values_:Array;
protected var disObjCont:DisplayObjectContainer;
public function DisplayObjectProxy(target:DisplayObject):*{
this._target_ = target;
this.disObjCont = _target_ as DisplayObjectContainer;
}
flash_proxy override function hasProperty(propName:*):Boolean {
//trace("hasProperty : " + propName);
return true;
}
flash_proxy override function getProperty(propName:*):* {
//trace("getProperty : " + propName);
var no:Number = parseInt(propName);
var isUint:Boolean = (no as uint) == no;
if (disObjCont != null) {
var child:DisplayObject = null;
if (isUint) {
if (disObjCont.numChildren > no) {
child = disObjCont.getChildAt(no);
}
//trace("child : " + child);
if (child != null) {
return new DisplayObjectProxy(child);
} else {
return null;
}
}
//trace("disObjCont : " + disObjCont);
child = disObjCont.getChildByName(propName);
//trace("child : " + child);
if (child != null) {
return new DisplayObjectProxy(child);
}
}
var prop:* = _target_[propName];
if (prop is DisplayObject) {
return new DisplayObjectProxy(prop);
} else {
return prop;
}
}
flash_proxy override function setProperty(propName:*, valueObj:*):void {
//trace("setProperty : " + propName, valueObj);
var no:Number = parseInt(propName);
var isUint:Boolean = (no as uint) == no;
if (_target_.hasOwnProperty(propName)) {
_target_[propName] = valueObj;
return;
}
if (disObjCont != null) {
if (valueObj is DisplayObject) {
if (isUint) {
if(disObjCont.numChildren > no) {
disObjCont.removeChildAt(no);
}
disObjCont.addChildAt(valueObj, no);
}
}
if (valueObj == null) {
if (isUint) {
if(disObjCont.numChildren > no) {
disObjCont.removeChildAt(no);
}
}
}
}
}
flash_proxy override function deleteProperty(propName:*):Boolean {
//trace("deleteProperty : " + propName);
var no:Number = parseInt(propName);
var isUint:Boolean = (no as uint) == no;
if (disObjCont != null) {
if (isUint) {
if(disObjCont.numChildren > no) {
disObjCont.removeChildAt(no);
return true;
}
}
}
return false;
}
flash_proxy override function callProperty(propName:*, ... rest):* {
//trace("callProperty : " + propName);
return _target_[propName].apply(_target_, rest);
}
override flash_proxy function nextNameIndex (index:int):int {
//trace("nextNameIndex : " + index);
if (index == 0) {
_keys_ = new Array();
_values_ = new Array();
if (disObjCont != null) {
var o:DisplayObject;
for (var i:Number = 0 ; i < disObjCont.numChildren ; ++i) {
o = disObjCont.getChildAt(i);
_keys_.push(o.name);
_values_.push(o);
}
}
}
if (index < _keys_.length) {
return index + 1;
} else {
return 0;
}
}
override flash_proxy function nextName(index:int):String {
//trace("nextName : " + index);
return _keys_[index - 1];
}
override flash_proxy function nextValue(index:int):* {
//trace("nextValue : " + index);
return _values_[index - 1];
}
}
}
DisplayObjectProxy Class 使用示范:
package {
import flash.display.*;
import flash.utils.*;
public dynamic class main extends MovieClip {
public function main():*{
test();
}
public function test():*{
// 将 Main 包覆为 DisplayObjectProxy
var mainProxy:* = new DisplayObjectProxy(this);
// 用 DisplayObjectProxy 添加四个 Child MovieClip
mainProxy[0] = new MovieClip();
mainProxy[1] = new MovieClip();
mainProxy[2] = new MovieClip();
mainProxy[3] = new MovieClip();
trace(this.numChildren); // 4
// 用 DisplayObjectProxy 指定四个 Child MovieClip Name
mainProxy[0].name = "mc1";
mainProxy[1].name = "mc2";
mainProxy[2].name = "mc3";
mainProxy[3].name = "mc4";
// 用 DisplayObjectProxy 依据 Child Name 取出对象
trace(mainProxy["mc4"].name); // mc4
trace(this.getChildAt(0).name); // mc1
trace(this.getChildAt(1).name); // mc2
trace(this.getChildAt(2).name); // mc3
trace(this.getChildAt(3).name); // mc4
// 用 DisplayObjectProxy 移除 index 为 2 的 child 方式之一
mainProxy[2] = null;
// 用 DisplayObjectProxy 列举所有的 children 方式之一
for (var i:* in mainProxy) {
trace(i);
}
// mc1
// mc2
// mc4
// 用 DisplayObjectProxy 移除 index 为 2 的 child 方式之二
delete mainProxy[2];
// 用 DisplayObjectProxy 列举所有的 children 方式之二
for each(var o:* in mainProxy) {
trace(o.name);
}
// mc1
// mc2
// 用 DisplayObjectProxy 对子对象容器再添加 Child
mainProxy[0][0] = new MovieClip();
mainProxy[0][0][0] = new MovieClip();
mainProxy[0][0][0][0] = new MovieClip();
mainProxy[0][0][0][0].name = "MC[0][0][0][0]";
// 用 DisplayObjectProxy 取出四层之下的 Child
trace(mainProxy[0][0][0][0].name);
// MC[0][0][0][0]
// 相较之下,AS3 正规方式相当复杂
trace(
(
(
(
(
this.getChildAt(0) as DisplayObjectContainer
).getChildAt(0) as DisplayObjectContainer
).getChildAt(0) as DisplayObjectContainer
).getChildAt(0) as DisplayObjectContainer
).name
);
// MC[0][0][0][0]
// 用 DisplayObjectProxy 取出不存在的 Child 对象
trace(mainProxy[0][0][0][2]);
// null
// 将 DisplayObjectProxy 脱壳
trace(describeType(mainProxy[0][0][0][0].valueOf()).@name);
// flash.display::MovieClip
}
}
}
相关连结:
AS3 DisplayObjectProxy 改版