是否有更好(更快,更短或更整洁)的方式来访问3层或更深的儿童精灵(物体)?如果孩子们都被给了名字,你知道这些名字。有没有比我下面的代码更好的方法呢?
var mySprite:DisplayObjectContainer = layerASprite.getChildByName(" layerA ")作为DisplayObjectContainer;
mySprite = mySprite.getChildByName(" layerB ")作为DisplayObjectContainer;
mySprite.getChildByName(" layerC ")。y = 200;
答案 0 :(得分:3)
如果它们是唯一的,您可以以静态类变量/方法的形式创建“全局”注册表:
package
{
public class Registry
{
static private var hash:Object = new Object;
static public function register(name:String, target:DisplayObject):void
{
hash[name] = target;
}
static public function access(name:String):DisplayObject
{
return hash[name];
}
}
}
用法:
// Any MovieClip, frame 1 or class constructor.
import Registry;
Registry.register("deepChild", this);
// From any other place.
import Registry;
Registry.access("deepChild").y = 200;
或者,您可以使用通过单个字符串参数挖掘子项的子项的方法:
function offSpring(path:String):DisplayObject
{
var aSplit:Array = path.split(".");
var result:DisplayObject = this;
while (aSplit.length)
{
var aParent:DisplayObjectContainer = result as DisplayObjectContainer;
if (!aParent) return null;
result = aParent.getChildByName(aSplit.shift());
}
return result;
}
用法:
offSpring("layerA.layerB.layerC").y = 200;
答案 1 :(得分:1)
由于我不是静态属性的忠实粉丝所以我也建议递归搜索:
public function findChild(d:DisplayObject, n:String):DisplayObject {
var dc:DisplayObjectContainer = d as DisplayObjectContainer; if (!dc) return null;
for (var i:int = 0; i < dc.numChildren; i++){
var ch:DisplayObject = dc.getChildAt(i);
if (ch.name == n || (ch = findChild(ch, n))) return ch;
}return null;
}
并且您可以直接输入:
var d:DisplayObject = findChild(stage, "childName");
在舞台上的任何地方找到名为childName
的第一个孩子。
我刚刚编写并测试了一次,但我希望没问题。
<强>优点强>:
DisplayObjectContainer
开始搜索。A
移动到容器B
,如果它仍然是同一分支的一部分且具有唯一名称,则不需要更改代码<强>缺点强>:
由于被搜查的孩子通常可以是给定容器的直接孩子,或者在更近的水平上,你可能会在一个时间点搜索孩子,尽管这有点棘手。例如我的alpha版本:
/**
* Perform parallel/sprial recursive search in this container to find child with given name.
* This means that this function will first check names of all child of this container and and then go to deeper level.
* In other words, no element will be tested on level x+1 if not all elements were tested on level x.
* This is true for all levels until whole tree is exhausted. This method is using token argument for such functionallity.
* @param n name of child element to be found.
* @param t token passed internally for sipral search. You should not specify this if you want the function to search a whole tree.
* The token has only single value which is basically a desired level at which child should be searched for.
* Level 1 means this function will only check its own childrens, level 2 means that only childs of childs of this container will be checked and so one.
* However note that if you specify a token with some level, only that single level will be searched.
* On the other hand if given token is null, this will check childs on level 1, then level 2, 3... and it will countinue until deepest level has been reached.
* @return nearest child with specified name or null if no child with given name found.
*/
public function findChild(n:String, t:SearchToken = null, ind:String = ""):SGLElement {
ind += " ";
var r:Boolean = (t) ? false : true; //is this call root of search.
t = (t) ? t.offL( -1) : new SearchToken(0); //create new token if not given or decrement current token value.
//trace(ind + "F", this.name, ":", t);
//if (!t) t = new SearchToken(0);
//--t.l;
var cl:SearchToken = new SearchToken(t.l); //current search level.
var exc:int = 0; //exhausted childrens.
if(t.l == 0){//search own children
for (var i:int = 0; i < _childs.length; i++) { //trace(ind + " c", _childs[i].name);
if (_childs[i].name == n) return _childs[i]; }
if (r) ++cl.l; else return null;
}
while( cl.l > 0){
if (exc >= _childs.length) { t.l = -1; return null;}
for (i = 0; i < _childs.length; i++) {
//trace(ind + "ch", t,":", i, _childs[i].name, _childs[i]);
if (!(_childs[i] as SGLElementContainer)) continue;
//trace(ind + "t", t, i);
t.l = cl.l;
var e:SGLElement = SGLElementContainer(_childs[i]).findChild(n, t, ind);
//++cl.l;
if (e) return e;
else if (t.l < 0) exc++;
}
//trace(ind + "END_LEVEL>>>>", t);
if (!r) return null;
//t.l = cl.l;
++cl.l;
}
return null;
}
令牌类
package adnss.common.utils
{
public class SearchToken
{
/**Current level**/
public var l:int;
public function SearchToken(levelValue:int) {l = levelValue;}
public function toString():String {return String(l);}
/**Set level value and return this token instance.**/
public function setL(v:int):SearchToken { l = v; return this; }
/**Add given offset value to level value and return this token instance.**/
public function offL(v:int):SearchToken { l += v; return this;}
}
}
我注意到我不知道这种搜索的技术名称是什么,所以我给它自己的名字,这个方法不用于显示列表,所以你需要调整它。这有点难以解释,但如果你有一些问题可以自由提问。