Click here to Skip to main content
Click here to Skip to main content

Windows XP Style Menu

, 13 Nov 2002
Rate this:
Please Sign up or sign in to vote.
Create a menu which looks like Windows XP PanelBar

Sample Image - WindowsXPStyleMenu.gif

Introduction

If you're using Windows XP you might feel familiar with the menu bar that appears in the left side of the Windows explorer. This article makes the same menu, that when you click on it, it'll collapse although it does not look as nice as the real one Smile | :)

This article also demonstrates the separation of structure, presentation and functions, thanks to Paul Watson for his wonderful DHTML Menu article which you shouldn't miss.

The structure (HTML)

For easily following this article, I demonstrate here the structure of the menu and some words I used in this article. Each menu follows exactly this structure.

  • Each menu contains 2 parts: the Menuhead and the Menulist.
  • Click on the Menuhead the Menulist will either expand or collapse.
  • The Menulist contains the Linkslist. All the links will be inside this part.

And here is the HTML code for the structure showed above. The complete HTML is in the source code.

<body onLoad="InitializeMenu()">
    <span>
    <div style="width:180">
    <table cellpadding="1" cellspacing="0" class="Menu_Head">
    <tr>
    <td width="90%">JavaScript</td>
    <td><img src="down.gif" border="0"> </td>
    </tr>
    </table>
    </div>
        <div class="Menu_Items">
        <div>
<a href="">There must be sth...</a><br>
<a href="">There must be sth...</a><br>
<a href="">There must be sth...</a><br>
<a href="">There must be sth...</a>
        </div>
        </div>
    </span>
    ....

The structure is quite simple as you can see, the menu is enclosed in the <span> tag. Inside the <span> are 2 <div>s, the first one is for the Menuhead, and the last one is for the Menulist. And inside the Menulist is another <div> which is the Linkslist as shown in the picture above. This Linkslist contains all the hyperlinks which belongs to this menu.

Since each menu has the same structure, if you want to add more menus, simply copy the code above and then change the title and its links.

The function InitializeMenu which is inside the <body> tag, is called when the page is loaded, to make the menu interactive.

The JavaScript

The JavaScript includes 4 functions which are quite complex. I'm going through each one here.

First, there are some variables I declared as global because each of them is used in almost all the functions

/* cache 2 arrow images */
imageUp = new Image();
imageUp.src = "up.gif";
imageDown = new Image();
imageDown.src = "down.gif";

/* for doing the loop */
var cnt;  
/* store a collecion of Menu */
var objSpanCollection; 
/* store a collection of Menulists' height */
var menuHeightCollection = new Array(); 
/* the menu is clicked on */
var objMenu;

Next is the InitializeMenu() which gathers a collection of Menus and assign the onClick event to every menu:

function InitializeMenu() 
{
    /* get a collection of menus */
    objSpanCollection = document.body.getElementsByTagName("SPAN");
    for (var i = 0; i < objSpanCollection.length; i++)
    {
    var objSpan = objSpanCollection(i);
    /* get a collection of Menus' height */
    menuHeightCollection[i] = objSpan.childNodes.item(1).clientHeight;
    /* assign the click event to every Menuheader */
    objSpan.childNodes.item(0).onclick = ControlMenu;
    }
}

The InitializeMenu() function uses the getElementsByTagName() to look through the entire HTML code and find all the <span> tags, because as we know each menu begins with this tag, so if 4 <span> tags are found, then we have 4 menus.

Next the code goes through every menu in the collection and get another collection of each Menulist's height, then assign the click event to each Menuhead.

function ControlMenu() 
{
  cnt = 1;
  /* memorize the Menulist has been clicked */
  objMenu = this.parentNode.childNodes.item(1);    

  /* Get the arrow that belongs to the clicked menu */
  /* starting with <div> then <table> */
  /* then <tbody> then <tr> then <td>*/
  /* and the last one is */
  /* what we need: <img> */
  var objArrow = 
   this.childNodes(0).childNodes(0).childNodes(0).childNodes(1).childNodes(0);
        
  if (objMenu.style.display == "none")
  {
    objArrow.src = imageDown.src;  /* change to the Down Arrow */
    ShowMenu();
  }
  else
  {
     objArrow.src = imageUp.src;  /* change to the Up Arrow */
     HideMenu();
  }
}

The ControlMenu() function is called when a user clicks on the Menuhead. This function is quite simple, first it remembers the Menulist of the menu that a user clicked on. Then if the menu is collapsed, it'll call the ShowMenu() method to expand the menu. Otherwise the HideMenu() method will be called to collapse the menu.

function ShowMenu()
{
    /* get the Linkslist of the Menulist */
    var objList = objMenu.childNodes.item(0);    
    if (cnt < 10)
    {
        /* display the Menulist */
        objMenu.style.display = "block";
        /* increase the tranparency of the Menulist */
        objMenu.filters["alpha"].opacity = 
            objMenu.filters["alpha"].opacity + 10;
        /* loop through the Menu collection to */
        /* find the position of the clicked Menu */
        /* to get the actual height of the menu list and then */
        /* increase the height of the Menulist */
        for (var i = 0; i < objSpanCollection.length; i++)
            if (objMenu.parentNode == objSpanCollection[i])
              objMenu.style.height = 
                objMenu.clientHeight + (menuHeightCollection[i]/10);
        cnt++;
        /* do this function again after 30 miliseconds until */
        /* the actual Menulist's height is returned */
        setTimeout("ShowMenu()",30)
    }
    /* display the Menulist if the its actual height is returned */
    if (cnt >= 10)
        objList.style.display = "block";  
}

The ShowMenu() method expands the menu by increasing the height and the transparency of the Menulist. Once this method is called it will be repeated 10 times by using the setTimeout() method. 30 milliseconds is the time waited before the ShowMenu() method will repeat.

Because this method is repeated 10 times, so each time the method will increase the transparency by 10 and the height by 1/10 the actual height of the Menulist. The ShowMenu() method gets the actual height of the Menulist by looping through the Menulist's height collection and find the suitable one.

function HideMenu()
{   
    /* get the Linkslist of the Menulist */
    var objList = objMenu.childNodes.item(0);    
    if (cnt < 10)
    {
        objMenu.filters["alpha"].opacity = 
           objMenu.filters["alpha"].opacity - 10;
        for (var i = 0; i < objSpanCollection.length; i++)
            if (objMenu.parentNode == objSpanCollection[i])
              objMenu.style.height = 
               objMenu.clientHeight - (menuHeightCollection[i]/10);
        objList.style.display = "none";
        cnt++;
        setTimeout("HideMenu()",30)
    }
    if (cnt >= 10)
        objMenu.style.display = "none";
}

The last method is the HideMenu() which does the same thing like the ShowMenu() method, but instead of increasing the transparency of the menulist, this method decreases them.

The CSS

There's nothing new with this CSS so I won't go into details here. Just copy to the top of the page and everything is done.

<style type="text/css">
    body {
        background-color: black;
    }
    a {
        color: darkblue;
        text-decoration: none;
    }
    a:hover {
        text-decoration: underline;
    }
    .Menu_Head {
        filter:alpha(opacity=100,finishopacity=80,style=1);
        background-color: whitesmoke;
        font-weight: bold;
        cursor: pointer;
        width: 100%;
    }
    .Menu_Items {
        filter:alpha(opacity=100);
        background-color: #c4d7ff;
        padding: 10;
        width: 180;
        display: block;
    }
</style>

Hope this helps.

<!--

Links

-->

Updates

  • November 14 2002

    Including the Up and Down Arrows. When the menu is expanded, the Up arrow will be shown otherwise the Down arrow will be shown.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Zek3vil

Singapore Singapore
No Biography provided

Comments and Discussions

 
GeneralXP STYLE MENU Pinmemberdharmendra25829-Dec-08 23:22 
Generalsdg Pinmembernaresh_nash22-Mar-06 21:29 
Generalnow,doesn't work with FireFox Pinmemberewebapp23-Dec-05 16:19 
GeneralQuite buggy. PinmemberDimitris Vassiliades21-Jul-03 20:51 
GeneralAutomatic closing menu, when opening another PinmemberLeighD21-May-03 7:19 
QuestionHow to start with hidden menus? PinmemberMauriceMG15-Apr-03 4:01 
AnswerRe: How to start with hidden menus? PinmemberZek3vil15-Apr-03 7:43 
GeneralRe: How to start with hidden menus? PinmemberMauriceMG15-Apr-03 20:19 
GeneralMozilla Version Pinmemberjpatel6-Feb-03 5:37 
QuestionMozilla? PinmemberMatt Newman19-Nov-02 16:24 
GeneralDoesn't work with IE6 PinmemberJean-Marc Molina19-Nov-02 3:56 
GeneralRe: Doesn't work with IE6 PinmemberZek3vil19-Nov-02 5:41 
GeneralRe: Doesn't work with IE6 Pinmembersoppy sky blue1-Sep-09 15:44 
GeneralAwesome PinmemberMatt Newman14-Nov-02 14:15 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web01 | 2.8.140721.1 | Last Updated 14 Nov 2002
Article Copyright 2002 by Zek3vil
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid