This snippet takes xml and builds a multi-tiered navigation based on how nodes are nested etc...:
So that something like this:
XML:
-
var menu:XML=<nav>
-
<element label="one">
-
<element label="a" />
-
<element label="b" />
-
<element label="c" />
-
</element>
-
<element label="two">
-
<element label="three">
-
<element label="aa">
-
<element label="zevan" />
-
</element>
-
<element label="bb" />
-
<element label="cc" />
-
</element>
-
</element>
-
</nav>;
Turns into an expandable and collapsible menu that looks like this:
Here is the timeline code:
Actionscript:
-
var menu:XML=<nav>
-
<element label="one">
-
<element label="a" />
-
<element label="b" />
-
<element label="c" />
-
</element>
-
<element label="two">
-
<element label="three">
-
<element label="aa">
-
<element label="zevan" />
-
</element>
-
<element label="bb" />
-
<element label="cc" />
-
</element>
-
</element>
-
</nav>;
-
-
var elements:Array = new Array();
-
setupMenu();
-
-
function setupMenu():void {
-
parse(menu);
-
// hide child elements
-
for (var i:int = 0; i<elements.length; i++) {
-
var mc:MovieClip = elements[i];
-
if (mc.parents != 1) {
-
removeChild(mc);
-
}
-
}
-
arrangeY();
-
}
-
-
function parse(m:XML):void {
-
for each (var d:XML in m.children()) {
-
makeBtn(d, numParents(d));
-
parse(d);
-
}
-
}
-
-
function makeBtn(d:XML, offsetX:int):void {
-
var btn:MovieClip = new MovieClip();
-
btn.x = offsetX * 20;
-
btn.y = numChildren * 20;
-
btn.data = d;
-
btn.parents = offsetX;
-
btn.value = d.@label;
-
-
var txt:TextField = new TextField();
-
txt.text = d.@label;
-
txt.selectable = false;
-
txt.border = true;
-
txt.width = 100;
-
txt.mouseEnabled = false;
-
txt.height = 19;
-
btn.addChild(txt);
-
btn.buttonMode= true;
-
addChild(btn);
-
-
// store references to btn
-
elements.push(btn);
-
elements[d.parent().@label+"_"+d.@label] = btn
-
-
btn.addEventListener(MouseEvent.CLICK, onClick);
-
}
-
-
function onClick(evt:MouseEvent):void {
-
showHide(MovieClip(evt.currentTarget));
-
arrangeY();
-
trace(evt.currentTarget.value);
-
}
-
-
function showHide(btn:MovieClip, forceHide:Boolean=false):void {
-
for each (var d:XML in btn.data.children()) {
-
var mc:MovieClip = elements[btn.data.@label+"_"+d.@label];
-
if (contains(mc)) {
-
removeChild(mc);
-
showHide(mc, true);
-
} else if (forceHide == false) {
-
addChild(mc);
-
}
-
}
-
}
-
-
function arrangeY():void {
-
var inc:Number = 0;
-
for (var i:int = 0; i<elements.length; i++) {
-
if (contains(elements[i])) {
-
elements[i].y = inc * 20;
-
inc++;
-
}
-
}
-
}
-
-
function numParents(e:XML):int {
-
var num:int = 0;
-
while (e.parent()!= null) {
-
num++;
-
e = e.parent();
-
}
-
return num;
-
}
This is one of those snippets I've had laying around but never got around to posting. Next time I need to do a multi-tiered nav I'll wrap it up into a nice class (the wondeful class was done just by using my script that auto-converts timeline code to doc class code).
2 Comments
How about adding some animation to it? That’s the icing on the cake! Keep up the awesome snippets!
i may post a revised version of it tomorrow… with some animation… would be easy enough to do with tweenlite….