Build a Dynamic Accordion Menu in Flash CS4 with ActionScript 3.0 and XML

by Mario Santos 142

In this tutorial you will learn how to build an accordion style menu from scratch that can be configured by using an external file.

The menu items can be totally configured in XML with label and can load text, image or swf on it’s open “state”. Just follow the tutorial, it’s quite simple. At the end you will see a second example achieved by this procedure.

Final Result

The final result of this tutorial is a fully functional XML configured flash menu that can load Text, Images or SWF files, like this one:


Adobe Photoshop CS 3/4 if you want to customize your menu – You can download free trial here

You will need Flash CS4 (but it will work also in previous versions).

Also need a menu item designed; can be any image, but I recommend to use mine that can be downloaded here, you will find the .psd file also so you can use your own style, but make sure you have the left side with 20px aprox.

Have the TweenLite Engine that can be downloaded here. Normally we did not need this, but i prefer using it than native AS3 tween classes.

You should feel fine about developing in Adobe Flash even if this tutorial is very simple to follow.

Download Source Files

Step 0 – Getting Started

The very first thing is to create a new Action Script 3 Project!

Then make the stage with these dimensions:

Save the file in a folder called menuAccordion with the name “tutorial”.

Step 1 – Create the menu Item

We will need only one menu item, the others we will re-create them from this one. We should do this way because our menu is dynamic, so… how we will do this, simply, we create a movie clip to behave as menu item, then export it to action script use, and then just need to duplicate him in action script.

The first thing to do is to import the image that I’ve made, go to menu File->Import-> Import to stage, this way the image is placed immediately on stage. I’ve used the “itemback1.jpg”:

Now convert it into a MovieClip, right-click on it, Convert to Symbol, and choose MovieClip, name it menuItem (important!), and click export to Action Script (Important), the things should be like the image (my OS is French, but the options are in the same place, should be easy to follow):

The correct names are very important because we will use it in Action Script. If an warning is shown, press ok.

Our menu needs some parts, a Text field to receive the label, then a textarea to display text is the user define it on the XML and a empty MovieClip to load JPG/SWF files, used to display content when menu is open.

Step 2 – Put content loaders in place

I mean, the label for the menu, the text and the empty movie clip:

Edit our recently transformed movie clip (double click on it), create a new layer above the existing, name it label and the first thing is to add a text field on the gray section, write on text: “HOME”, on properties choose dynamic text, with embed characters (important!), align left and single line. Size it according to accordion height and give it a black-gray color.

You cannot see the text HOME? You forgot to embed characters right? Embed the uppercase chars only and name this instance itemLabel!

Create a new layer and name it buttonBack, then draw a rectangle over all the gray area:

Convert this rectangle into a MovieClip, name it buttonBack (do not export for action script) and then name this instance into “buttonBack” and put the alpha to zero, in Style Combobox.

The next thing to do is to create a content loader. Create a new layer and label it contentLoader, next we need to draw a rectangle, according to the image right size:

Transform it in a MovieClip called itemLoader, name the instance name to itemLoader and double click on it and click on the Right-Click on it and select Guide, this apparently will do nothing, but when you go back to the menu is simply disappeared, but that is not 100% true, it is there on the layer but with a transparent background…

Now create a new Layer always on the top of all, and name it text, draw here a text like the image, make it as Dynamic text, center align, and if needed embed characters. Name his instance as itemText.

Well, you menu item is done! Just need now to write the XML file, and make some action script code.

Before, just check if your layers order is like this:

Step 2 – Write the XML

Create a xml file called menu.xml and write this down!:

<?xml version="1.0" encoding="utf-8"?>
  <menu menuOpen="1" moveOnMouseOver="false">
  		 <item Ititle="home" IcontentType="image/swf" IcontentData="image2.jpg"/>
 		 <item Ititle="about" IcontentType="text" IcontentData="Our company is based on UK! Know how we have born!; Click here"/>
  		 <item Ititle="Products" IcontentType="image/swf" IcontentData="image5.jpg"/>
 		 <item Ititle="Services" IcontentType="image/swf" IcontentData="item2.swf"/>
 		 <item Ititle="Contact" IcontentType="image/swf" IcontentData="image1.jpg"/>

The xml structure is quite simple, the menuOpen property will define the menu tab taht will open automatically on start, then the moveOnMouseOver indicates if the menu item should open when the mouse over it’s tab. Then the items, in Ititle we define the label for the menu, will be used in the itemLabel text field, then the type of content (IcontentType) that the menu will load, if its =”text” the itemText text field will load the IcontentData text, or if is “image/swf” the contentLoader will load the IcontentData object url.

Save this file and put also the gs folder of downloaded Tweenlite AS3 into the same folder as the main Flash file (menuAccordion).

Now go back to Flash, on the main stage we got only one menuItem right? right-click on it an choose Cut (CTRL+X), now create a new MovieClip (menu Insert -> New Symbol and name it menuLoader, press ok and then past our menuItem (CTRL+V), the position is not important.

Go back to main stage, open library panel and drag the menuLoader into the first layer, the things are equal, but this time we got a menu loader where the menu items will be loaded. Name this instance menuContainer.

Lets add a new Layer on the stage and name it mask, on it design a rectangle, convert it to a movieclip and name it masker. Name its instance also as masker. Right-Click on that Layer and then Mask it, this mask will be used to avoid the last menu to be shown when we don’t want!

Now, add a third layer on top of those two, name it Actions, go to actions panel and write this down.

//import tweenlite classes
  import gs.TweenLite;
  import gs.easing.*;

  var MENU_ARRAY:Array; //used to save the items data
  var OPENED_MENU:int; //to inform the menu that should be open at startup
  var MOVE_ON_MOUSE_OVER:Boolean=false; //tha name says everything
  var xmlLoader:URLLoader; //the xml loader

loadXML("menu.xml"); //load the xml

function loadXML(Uri:String):void {
  xmlLoader = new URLLoader();
  xmlLoader.addEventListener(Event.COMPLETE, onComplete);
  xmlLoader.addEventListener(IOErrorEvent.IO_ERROR, onError);
  xmlLoader.load(new URLRequest(Uri));

function onError(evt:ErrorEvent):void {
  trace("cannot load xml file");

function onComplete(evt:Event):void {
  //read and load xml into array, by parsing it using prepareMenu
  placeItemsOnStage(); //place all required items on stage.

function placeItemsOnStage():void {
	var pos:Number=0;
  //define the container properties

	for(var c:int=0; c<MENU_ARRAY.length; c++) {
	  var it:menuItem = new menuItem; //load out menuItem, because its exported to AS, we can use it here
	  	it.x=c*27; //its the gray border width
  		it.y=0; //place on top"Item-"+c; //id the menuItem"Item-"+c; //name de menuItem
  		it.posX=pos; //actual pos, useful to open and know is position
  		it.itemLabel.text=String(MENU_ARRAY[c].Ititle).toUpperCase(); //load the label in uppercase
  		it.addEventListener(MouseEvent.CLICK, onMouseClick); //add mouse click listener
  		if(MOVE_ON_MOUSE_OVER==true) it.addEventListener(MouseEvent.MOUSE_OVER, onMouseOver); //if configured, load the mouse over event
  		it.useHandCursor=true;  //use hand cursor
  		it.buttonMode=true; //buttonMode
  		it.itemText.visible=false; //hide the textField
  		menuContainer.addChild(it); //add the menu item as child

		 if(String(MENU_ARRAY[c].IcontentType)=="image/swf")	{ //check the content and load things accordint to it
		  	var ldr:Loader = new Loader();
  			ldr.load(new URLRequest(MENU_ARRAY[c].IcontentData.toString()));
		else if(String(MENU_ARRAY[c].IcontentType)=="text") {
	pos+=27; //the next menuItem x position

 //put mask in place

 moveItem(OPENED_MENU-1); //open menu confirured in XML


  function onMouseOver(evt:MouseEvent):void {
  	if("buttonBack") prepareMove(evt)

function prepareMove(evt:MouseEvent):void {
  var targetName:String =; //get the menuItem
  var temp:Array = targetName.split("-"); //split his name: Item-x
  var itemNumber:int=(temp[1]); //got item number
  moveItem(itemNumber); //move it

function onMouseClick(evt:MouseEvent):void {
  if("buttonBack")  prepareMove(evt); //mouse action was done in buttonBack
  else trace("Item "" clicked!"); //mouse action was made on accordion area

function moveItem(num:int):void {
  var itemToMove:menuItem=menuContainer.getChildByName("Item-"+String(num)) as menuItem;
  //get the menuItem child
  for(var m=0;m<MENU_ARRAY.length;m++) //move one-by-one to the new position
  var tempMc = menuContainer.getChildByName("Item-"+m);
  if(tempMc.x > itemToMove.x), 1, {x:((tempMc.posX) + itemToMove.width-27), ease:Quart.easeOut}); //see tweenLite for info about this.
  else if(tempMc.x <= itemToMove.x), 1, {x:(tempMc.posX), ease:Quart.easeOut});

function prepareMenu (XMLData:String):Array
  //make sure it cames in XML
  var menuXML:XML = new XML(XMLData);
  //just in case
  menuXML.ignoreWhitespace = true;

  //get XML item's entrys
  var XMLItems = menuXML.descendants("item");

 //load all items into an array
  var itemsArray:Array = new Array();
  var itemObj:Object;
  for(var i in XMLItems)
  itemObj=new Object();
  itemObj.Ititle=XMLItems[i][email protected];
  itemObj.IcontentType=XMLItems[i][email protected];
  itemObj.IcontentData=XMLItems[i][email protected];
  [email protected]; //get menu for open.
  MOVE_ON_MOUSE_OVER=([email protected]()=="true" ? true : false); //get the option for load or not mouseOver open
  return itemsArray;


The code is commented, so read it carefully before perform some actions, after that you just need to have some fun and make your own accordion menus! In the XML you can add, remove and edit accordion labs and items easily.

The last thing we need to do is to double-click the menuContainer / menuLoader and delete the menuItem there, we do not need it here because we will add it as child via AS3. Change the stage height to 200px (it’s the menu height).

One more example:

Hope you like it! You can download the final flash project here. Don’t forget to help us grow, by submitting this article to your favorite social networking using the bellow buttons.

Comments (142)

  1. Hi, love your tutorial! thank you very much I’ve used it twice in projects! But I have a minor problem: My menu text field is written in lowercase lettering and is ment to, but when i load the swf file, it is shown in uppercase lettering..? I don’t know how to correct this, because my “embedding” is covering all signs, and when i make it “lowercase only” it doesn’t show the menu text in the swf…Hope you have the solution 🙂

    thank you so much again 🙂


    1. Lea I was having trouble with the accordion tutorial and I have gone through it over and over careful not to miss a detail. I was wondering since you have completed successfully more than once…was there anything that you did or had to adjust outside of what was in the tutorial or that wasn’t mentioned? Hope you can help thanks.

  2. Hola mario como puedo adaptarlo a otras dimensiones como por ejemplo 640px x 480px???

  3. Hi,

    Sorry I’m french but I have a little problem.
    I want to resize the accordion to 631x343px so I have enlarged the itemback in this format. I enlarged to the masker width
    —> masker.width=(MENU_ARRAY.length*27+631)
    I have item, all images, and there are two first buttons wich appear on the left and nothing on the right ! And when I click on the first button, the other dissapear to the right…

    Can you help me ?
    I’m sorry for my english but I can’t use the web translators, there are too useless^^

  4. i really wanna get this done…i have d same prob as JOE

    TypeError: Error #1010: A term is undefined and has no properties.
    at accordionmenu_fla::MainTimeline/placeItemsOnStage()
    at accordionmenu_fla::MainTimeline/onComplete()

    i didnt really undrstand thse part:
    The last thing we need to do is to double-click the menuContainer / menuLoader and delete the menuItem there, we do not need it here because we will add it as child via AS3. Change the stage height to 200px (it’s the menu height).

    How is the deletion to be done?i just pressd del

    1. TypeError: Error #1010: A term is undefined and has no properties.
      at tutorial_fla::MainTimeline/placeItemsOnStage()
      at tutorial_fla::MainTimeline/onComplete()

      i do also have the same problem with tuck and joe.. could please help us??

      1. Did you ever get a solution to your TypeError: Error #1010: with your Flash Accordion?

        I’m baffled. Any help would be much apprecitated. My error is :

        TypeError: Error #1010: A term is undefined and has no properties.
        at Mod2_L1_S1_fla::MainTimeline/onClick()

        I have some buttons which call this error.

  5. ok.i ws succesful in changing the size acc to my needs but cant figure out how to remove extra white space between panel…is it something to do wid actionscript or the fla file??? i think i need to change sonething in the instance “backText”….plz reply

  6. I wanna hyperlink the text item to local files. Can you please tell me how ?

  7. Great Job!
    I will try to convert it to AS2 project 🙁

  8. Hey, great tutorial, accordian worked great. But i was wondering, if I were to try and re-create the same effect onto a document thats 728×90, or any other size for that matter, how would I go about doing so?

    Any help will be much appreciated……..

  9. Hoping to do a couple of things– change the size to 750 x515 and also add more items to the banner the tutorial has 5 but I would like 11. Any help would be great– I’ve tried changing various numbers in the AS but it gets funky on me.

  10. hi
    i really liked the tutorial i just want to know one thing
    how how how to i make this so when i click one of the pictures it goes to a simple web page lol

    1. Hi Ryan,

      if you look for the following:

      function onMouseClick(evt:MouseEvent):void {
      if(”buttonBack”) prepareMove(evt); //mouse action was done in buttonBack
      else trace(“Item “” clicked!”); //mouse action was made on accordion area

      You can see that if the mouse is clicked inside the accordian area, NOT the tab/button, the else condition fires up and this is where you can put your url links I would say.

      Hope that helps.

  11. I have gone through the tutorial several times and I’m sure I am missing something very small but it seems that when I create the mask and then try to publish, it says mask is an undefined property. If I publish before actually masking the layer it shows up obviously blocking the content so somehow when I mask the layer something is going wrong. Any ideas?

    1. Just make sure your mask is converted to a movie clip with an instance name of “masker” and it’ll work.

  12. For those with this error:
    TypeError: Error #1010: A term is undefined and has no properties.
    at tutorial_fla::MainTimeline/placeItemsOnStage()
    at tutorial_fla::MainTimeline/onComplete()

    I found it was an instance name issue with the itemLabel text field. Renaming it solved that problem!

    Haven’t seen anyone post an answer to the re-sizing questions, so here goes…

    I resized a copy to 700px (the height doesn’t seem to make any difference that I’ve noticed) and had extra tabs too (6 in total at 30px wide).

    I found you have to change two parts of the AS code, depending on the width of the tabs and the overall width of the swf.

    The first part is setting the masker width as follows:

    //put mask in place
    //this next line is the one to alter, and for a 700px wide swf with 6 tabs, it should read as follows
    //6 * 30 =180 + 520 = 700

    If you get an undefined property error on masker, just turn your mask into a movie clip and call it masker, or as I did at first, comment out the above code, set your mask as you would usually (ie the same size as your stage, and set it to mask via the layer panel. Seemed to work for me!

    secondly, you have to alter the Tweens way down near the bottom, in the moveItem function.

    Here’s how it looks:

    if(tempMc.x > itemToMove.x), 1, {x:((tempMc.posX) + itemToMove.width-27), ease:Quart.easeOut}); //see tweenLite for info about this.
    else if(tempMc.x <= itemToMove.x), 1, {x:(tempMc.posX), ease:Quart.easeOut});

    In the IF statement, the bit that says "{x:((tempMc.posX) + itemToMove.width-27", I changed mine to "{x:((tempMc.posX) + itemToMove.width-180", ie the number of tabs (6) * the width of the tabs (30) and it all works beautifully.

    You might have to resize the itemText dynamic textfield size and placement, to make sure you can see it all when the tabs are in place, but this is easily enough done by eye back in the main timeline.

    Took me a while, but hopefully it's of some use to those who may still be struggling. Good luck!

  13. Hi.

    Thanks for a great tutorial. I’ve been tried to change the site like you said in your last comment, and it work for me.

    But now I’ve been trying to put a picture in insteed of the text at the grey area, but with no luck.

    Is it possible to get a picture in there and how can I do it?

    I’ve been trying with a image tag: – Which not worked.
    Next I added the following in the AS code:

    else if(String(MENU_ARRAY[c].Ipic)==”image”){
    var ldr2:Loader = new Loader();
    ldr2.load(new URLRequest(MENU_ARRAY[c].Ipic.toString())); }

    But neither that worked. So.. is it something you can help with? I will be very thankful if you can, couse I’ve been working with it for a month :/

    Looking forward to hear from you


    1. Hi Mie,

      Do you mean to put a picture on the grey ‘tab’ (the button bit!)? If so , I think there should be a couple of ways to do that..

      As the tab and background are only a picture (.jpeg/.png/.gif etc), you could always add your picture to it before you start with all the scripting stuff, making it a part of the actual background if you like.

      If you wanted to put the picture there using xml… as well as making the ‘contentLoader’ for loading the text/images in to the pages, you could at the same time make an ‘imageLoader’ for the tabs, and follow the same procedure, just using a different xml file and a new array to suit. As the button etc on the tab is transparent anyway, it shouldn’t stop you seeing the imported image.

      Does that make any sense?!

      Think I’d go with the first option!

      1. Hi Simon.

        Thank you very much for your reply.

        The first option is the easy way I see, but I want to have different pictures at the grey area, so I think your option 2 is the right way to do it. It give sense and I will try that 🙂 I just thought that it was possible to load image in the first xml, but after some reseach I find out that it’s not so easy, because it’s a textfield 😛

        I will write you if I succeed 😉


        1. Hi again.

          Well, now I’ve been trying a lot of stuff, but with no result, except a lot of errors 🙂

          So.. I want a different picture at the grey area, and I’m trying to work with your option 2, create a imageLoader and a different xml-file.
          I’ve done that, and now I’m working with the AS. I have the following code right now:

          var xmlLoader:URLLoader = new URLLoader();
          var xmlData:XML = new XML();

          xmlLoader.addEventListener(Event.COMPLETE, loadXML);
          xmlLoader.load(new URLRequest(‘test.xml’));

          function loadXML(e:Event):void {
          xmlData = new XML(;
          trace(xmlData.image[0].filename); }

          var filenames:Array = new Array();
          filenames[0] = ‘some_image.jpg’;
          filenames[1] = ‘some_other_image.jpg’;
          filenames[2] = ‘and_another.jpg’;

          const IMAGES_DIRECTORY:String = ‘images/’;
          var loaders:Array = new Array();
          var movieClips:Array = new Array();

          function createLoaders(filenamesAsArray:Array, directory:String):void {

          for(var i:int = 0; i < filenamesAsArray.length; i++) {
          loaders[i] = new Loader();
          loaders[i].load(new URLRequest(directory + filenamesAsArray[i])); loaders[i].contentLoaderInfo.addEventListener(Event.COMPLETE, imageLoaded); } }

          function imageLoaded(e:Event):void {
          if( {
          var mc:MovieClip = new MovieClip();
          var bmp:Bitmap = new Bitmap(;
          addChild(movieClips[movieClips.length – 1]); } }

          With this code I'm making a Array to a movieclip, but the error is that I'm duplicating the function. I've never been loaded two xml-files to flash before. I have made some reseach and find out that I have to make a container? I can see you have made that too in the code, but why do I have to make anotherfor the imageLoader, when the imageLoader is in the menuItem-symbol?

          Do you think you can explain, or maybe help, or refer to a tutorial or something? Cause this will not work for me 🙂

          Best regards

          1. Hi Mei,
            Isn’t it frustrating when you think you’ve cracked it just to see the output box blink to tell you it’s all wrong!

            Imagine your file as a folder structure… you have:
            inside of which is menuItem
            inside of which is itemLoader. This only loads the xml file (“menu.xml” in the tutorial) that contains the content.

            Alongside itemLoader, (ie inside menuItem), you need to create a new loader (imageLoader) to load your images.xml file.

            What content type do you have in your “menu.xml”? Are they all text? or a mixture? I’ve got a work around if they’re all text, by using the “if” statement in the placeItemsOnStage function to place them differently (ie x = 0) if they are the “image/swf” type.
            It works this way, and you can add another field to the xml file to still show text as well

            Don’t know if that will help any, I’ll have a play later and see if I can find a better way.

  14. Hi Mei,

    Cracked it!

    Forget all I said about new arrays and xml files. Sorry!

    First, you need to edit your xml file. Add a new string called IcontentImage to the end of each item, so they look like this:

    where 6.png is obviously pointing to your images inside the same folder as the xml and flash files.

    Then on with the AS!

    Inside the placeItemsOnStage function, paste the following:

    var imageLoader:Loader = new Loader();
    imageLoader.mouseEnabled = false;
    imageLoader.load(new URLRequest(MENU_ARRAY[c].IcontentImage.toString()));

    I put mine just above menuContainer.addChild(it);

    Then, near the bottom, in the prepareMenu function, add the following:

    itemObj.IcontentImage=XMLItems[i][email protected];

    You’ll see where it goes…

    Then just jump up and down with joy!


    1. Sorry, there’s a bit missing…
      The xml items should look like this…

      1. Ok, third attempt!

        You’ll have to imagine the opening and closing tags around the following…

        item Ititle=”donate” IcontentType=”text” IcontentDataTitle=”donate” IcontentData=”Donate” This is the new bit:IcontentImage=”6.png”</strong

        1. Hi Simon.

          Thank you very much for your work!

          I will try working with that method that you suggests. It seems more right than what I’ve trying. Because I find out to put a image in the xml, and then change a little in the code. As this way I’ve got different pictures in, but the area that opens the menu items will not work.

          I really appreciate your helpfulness


  15. Hello 🙂 first things first – big thanks for this tutorial – it was pleasure. I managed to change size of my accordion, bu lately I got some serious problem:

    this line:
    else navigateToURL(new URLRequest(“ako/””.pdf”),”_new”);

    had wrong “” (italic ones) but when I get that I found bigger problem, as you can all see this line is getting from folder “ako” pdf file which name is Item-x (x is number according to pages of accordion menu where 0 is first). My problem is that I wanted use files that I already have in that directory. Best thing will be doing this by xml (I was trying adding IcontentURL content to xml but my abbilities of implementation xml code to actionscripts are… poor. Poor is a very good word for that).

    So my only way of getting this done is to ask for help you guys. Please – pretty pretty please – help me 🙂
    And one more time thanks for the tutorial Mario Santos!

  16. Haven’t used flash for a while, use to design entire sites on it. I’ll give it a go. Very well explained.

  17. can i make this menu with buttons inside of it instead of images, text or swf’s??? and i need it to be vertical. like with buttons

  18. Thanks for a great tutorials

  19. This is a great tutorial, I have everything working as it should and am very pleased with this, but I am wondering if there is a way to get the banners to load evenly distributed instead of having one of them being initially opened?

  20. Great Tutorial!!!

  21. hi mario..
    first of all, great tutorial!
    i have a little favor if you dont mind…. im kinda new to flash thats why im having difficulties making some codes… i want it to automatically change to the next menu item by about 5 seconds and whenever the pointer hovers a certain menu, the timer stops, and when the pointer leaves the menu, it resumes the timer starting with the currently viewed menu… i would really appreciate any help…. and thanks for this wonderful tutorial.

  22. Hi Mario,

    The tutorial is very good , but when I downloaded it I am not able to ople FL file, it says unexpected file format, I am using FlashCS3, it is said in the tutorial that it has been made in FlashCS4 but should work in lower version as well, pl. someone help me how to open flash file, why its not opening in flashCS3 can it be available in FlashCS3 ? I really need this pl. pl. help.

  23. Hello
    you for the script.
    Now i want to know how can i create a link to my content page in my xml file.

    Bonjour à tous;
    Merci déjà pour ce script très intéressant. mais j’aimerais savoir comment faire pour créer un lien a partir d’un item vers une page web dans mon fichier xml.
    j’ai essayé comme ceci mais ça marche pas.

  24. is there any way to get two of these in the same movie? as in, an accordion on one “page” of a website and a different accordion on another “page” of the website? I keep getting the error that “menuItem” has already been used and can’t be used again… But i made two different accordions! I kinda need to use them both! Thank you to anyone who can help me! 🙂

    1. Can you not use ‘menuItem2’ or a similar dissimilar name for the new page’s menu? As long as all references are the same (including XML files etc) it should be a completely new menu on a different page.

  25. Is it possible to make the menu items change color when you hover your mouse over them?

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>