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.
<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
imageUp = new Image();
imageUp.src = "up.gif";
imageDown = new Image();
imageDown.src = "down.gif";
var cnt;
var objSpanCollection;
var menuHeightCollection = new Array();
var objMenu;
Next is the InitializeMenu()
which gathers a collection of Menus and assign the onClick
event to every menu:
function InitializeMenu()
{
objSpanCollection = document.body.getElementsByTagName("SPAN");
for (var i = 0; i < objSpanCollection.length; i++)
{
var objSpan = objSpanCollection(i);
menuHeightCollection[i] = objSpan.childNodes.item(1).clientHeight;
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;
objMenu = this.parentNode.childNodes.item(1);
var objArrow =
this.childNodes(0).childNodes(0).childNodes(0).childNodes(1).childNodes(0);
if (objMenu.style.display == "none")
{
objArrow.src = imageDown.src;
ShowMenu();
}
else
{
objArrow.src = imageUp.src;
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()
{
var objList = objMenu.childNodes.item(0);
if (cnt < 10)
{
objMenu.style.display = "block";
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);
cnt++;
setTimeout("ShowMenu()",30)
}
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()
{
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.
Updates
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.