Description
This script provides a non-JavaScript dependent tree menu. In the absense of JavaScript, the menu will automatically start minimized, thus remaining accessible to those without JavaScript enabled.
Demonstration
Implementation
The trick that makes this menu work is the fact that it uses JavaScript to minimize the menu as soon as it loads. Basically, it is set up like this. Each item is contained in a <div>. The subitems need to be contained in their parent's <div>. So, if you want a menu that has the first level item with one submenu item, and then one other top level item, the code would look like this:
<div id="menu_container">
<div class="item"><span><img src="images/minus.gif" width="9" height="9"> one</span>
<div class="item"><a href="#">two</a></div>
<div class="item"><a href="#">three</a></div>
</div>
<div class="item"><a href="#">four</a></div>
</div>
<script type="text/javascript">
if (document.getElementById) { //if DOM compliant
init();
}
</script>
Note how the two subitems are contained inside their parent item's <div>. Also, the bit of JavaScript that comes right after the menu is what tells compliant browsers to minimize the menu.
If you need certain items to start in the down position, you can use the startup variable at the top of the script to do this. There is a comment in the script directly below this variable that explains how it works.
Images Needed (right click -> save as)
![]()
Code
<style type="text/css">
#menu_container {
color: #527FA8;
background: #f5f5f5;
border: 1px solid #819ebb;
width: 200px;
padding: 3px;
}
.item {
cursor: default;
margin-left: 15px;
display: block;
}
#menu_container a {
color: #527FA8;
background: transparent;
text-decoration: none;
}
</style>
<script type="text/javascript">
/*#####################################################
# This script is Copyright 2003, Infinity Web Design #
# Written by Ryan Brill - [email protected] #
# All Rights Reserved - Do not remove this notice #
#####################################################*/
startup = ""; //Comments on this below
/*
* COMMENTS ABOUT THE startup VARIABLE -
* Leave the startup variable blank to run as normal, enter 1 to start with the entire menu maximized.
* Additionally, each item can be either be displayed or not displayed in the following fashion:
* 1|1|1|1|0|0|1|1 where 1's mean to display, and 0's mean not to display. So, in that
* example, the first, second, third and fourth items would be displayed, the fifth and
* sixth would not be displayed, and the seventh and eigth would be displayed on startup. Be sure
* you set all top level items (items without submenus) to 1, or they will never be displayed!
*/
function init() {
menu = document.getElementById("menu_container"); //get the container element
spans = menu.getElementsByTagName("span"); //grab all the spans
for (i=0; i<spans.length; i++) {
spans[i].onclick = showhide; //set the onclick to run the showhide funcion for each span
}
/*Initialize the menu. For browsers without JavaScript enabled, it will remain in it's down state*/
divs = menu.getElementsByTagName("div"); //grab all the divs
str = "";
allcookies = document.cookie; //get the cookies
if (allcookies) {
pos = allcookies.indexOf("menu="); //get the position of the start of our cookie
if (pos != -1) {
start = pos + 5; //set start to the beginning of our cookies value
end = allcookies.indexOf(";", start); //get to the end of our cookie
if (end == -1) {
end = allcookies.length; //or get to the end of all cookies (if it is the last one)
}
str = allcookies.substring(start, end); //grab our cookies value (from start to end)
}
else if (startup != "") { //if startup is not blank
str = startup; //grab the values out of startup
}
}
if (str.length > 0) { //if we found the cookie to set display to block or none
str = str.replace(/1/g, "block"); //replace 1 with block
str = str.replace(/0/g, "none"); //replace 0 with none
str = str.split("|"); //split at the pipe
while (str.length <= divs.length) { //if we have more divs that display (block|none) to fill it with
str[str.length] = "block"; //fill array with blocks
}
for (i=0; i<divs.length; i++) {
if (str[i] == "block") { //if it needs to be block
divs[i].style.display = str[i]; //display
}
else {
divs[i].style.display = str[i]; //hide
}
if (divs[i].childNodes[0].childNodes[0].src != undefined && str[i+1] == "none") { //if div contains an image, and if the next div's display is none
divs[i].childNodes[0].childNodes[0].src = "images/plus.gif"; //set image for down state
}
}
}
else {
for (i=0; i<divs.length; i++) {
child = divs[i].getElementsByTagName("div"); //grab all the child divs
for (j=0; j<child.length; j++) {
child[j].style.display = "none"; //hide
}
if (divs[i].childNodes[0].childNodes[0].src != undefined) { //if the div contains an image
divs[i].childNodes[0].childNodes[0].src = "images/plus.gif"; //set image for down state
}
}
}
}
function showhide() {
obj = this.parentNode; //get parent element (div in our case)
elems = obj.childNodes; //get child nodes
for (i=0; i<elems.length; i++) {
if (elems[i].tagName == "DIV") { //if child node is a div
if (elems[i].style.display == "none") { //if elemnt is
elems[i].style.display = "block"; //display
this.childNodes[0].src = "images/minus.gif"; //set image for down state
}
else {
elems[i].style.display = "none"; //hide
this.childNodes[0].src = "images/plus.gif"; //set image for up state
}
}
}
menu = document.getElementById("menu_container"); //get the container element
divs = menu.getElementsByTagName("div"); //grab all the divs
val = "";
for (i=0; i<divs.length; i++) {
display = (divs[i].style.display == "" || divs[i].style.display == "block") ? 1 : 0; //set display to 1 or 0 depending on the display value of the div
val += display+"|"; //concatenate the value
}
val = val.substring(0,val.length-1); //strip off the final pipe (|)
document.cookie = "menu="+val;
}
</script>
</head>
<body>
<div id="menu_container">
<div class="item"><span><img src="images/minus.gif" width="9" height="9"> one</span>
<div class="item"><a href="#">two</a></div>
<div class="item"><span><img src="images/minus.gif" width="9" height="9"> three</span>
<div class="item"><span><img src="images/minus.gif" width="9" height="9"> four</span>
<div class="item"><span><img src="images/minus.gif" width="9" height="9"> four</span>
<div class="item"><a href="#">five</a></div>
</div>
</div>
</div>
<div class="item"><a href="#">six</a></div>
</div>
<div class="item"><a href="#">seven</a></div>
</div>
<script type="text/javascript">
if (document.getElementById) { //if DOM compliant
init();
}
</script>
Tested in: IE6, IE5.5, IE 5, IE 4, Netscape 7, Netscape 6 Netscape 4.7, Mozilla Firebird, Mozilla 1.4, and Opera 7.
Works or degrades well in: IE6, IE5.5, IE 5, IE 4, Netscape 7, Netscape 6 Netscape 4.7, Mozilla Firebird, Mozilla 1.4, and Opera 7.
Doesn't work or doesn't degrade work in: N/A
Copyright© 2003, Infinity Web Design