Click here to Skip to main content
15,884,836 members
Articles / Programming Languages / Javascript
Article

Windows XP Style Menu

Rate me:
Please Sign up or sign in to vote.
4.29/5 (15 votes)
13 Nov 20023 min read 153.8K   2.8K   56   14
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 :)

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.

HTML
<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

JavaScript
/* 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:

JavaScript
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.

JavaScript
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.

JavaScript
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.

JavaScript
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.

HTML
<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.

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


Written By
Singapore Singapore
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralXP STYLE MENU Pin
dharmendra25829-Dec-08 23:22
dharmendra25829-Dec-08 23:22 
Generalsdg Pin
naresh_nash22-Mar-06 21:29
naresh_nash22-Mar-06 21:29 
Generalnow,doesn't work with FireFox Pin
ewebapp23-Dec-05 16:19
ewebapp23-Dec-05 16:19 
GeneralQuite buggy. Pin
Dimitris Vasiliadis21-Jul-03 20:51
Dimitris Vasiliadis21-Jul-03 20:51 
GeneralAutomatic closing menu, when opening another Pin
LeighD21-May-03 7:19
LeighD21-May-03 7:19 
How can I modify the script so that an open menu will close automatically when I click on another menu to open it?
QuestionHow to start with hidden menus? Pin
MauriceMG15-Apr-03 4:01
MauriceMG15-Apr-03 4:01 
AnswerRe: How to start with hidden menus? Pin
Zek3vil15-Apr-03 7:43
Zek3vil15-Apr-03 7:43 
GeneralRe: How to start with hidden menus? Pin
MauriceMG15-Apr-03 20:19
MauriceMG15-Apr-03 20:19 
GeneralMozilla Version Pin
6-Feb-03 5:37
suss6-Feb-03 5:37 
QuestionMozilla? Pin
Matt Newman19-Nov-02 16:24
Matt Newman19-Nov-02 16:24 
GeneralDoesn't work with IE6 Pin
Jean-Marc Molina19-Nov-02 3:56
Jean-Marc Molina19-Nov-02 3:56 
GeneralRe: Doesn't work with IE6 Pin
Zek3vil19-Nov-02 5:41
Zek3vil19-Nov-02 5:41 
GeneralRe: Doesn't work with IE6 Pin
soppy sky blue1-Sep-09 15:44
soppy sky blue1-Sep-09 15:44 
GeneralAwesome Pin
Matt Newman14-Nov-02 14:15
Matt Newman14-Nov-02 14:15 

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

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