|
|||||||||||||||||||||
|
|||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
SummaryA strictly structure, presentation and function seperated n depth DHTML menu. The power of HTML coupled with CSS and JavaScript is illustrated.
RequirementsTo view the demo and run the source: Internet Explorer 6 (no ASP or any other server side support required.) To follow this article: Basic HTML and medium to expert CSS and JavaScript skills. UpdatesI prefer notifying people of updates at the top of the article
IntroductionThere is an endless list of DHTML menu samples on the world wide web. From intricate cross browser samples to extravagant DirectX enabled wonders. This article demonstrates a DHTML menu that is none of these, what it does demonstrate is how to create a DHTML menu which has strict seperation of structure, presentation and function. Seperation of these three areas is important for the following reasons:
The MenuThe actual menu is very simple. It consists of three parts: The HTML (structure and content), the CSS file (presentation or style) and the JavaScript file (function or workings.) The menu can display as much depth (sub-menus) as you need, though of course screen real estate can become a practical concern if you go too deep. Also each menu list can display as many menu items as you need, with as many sub-menus in one list as is needed. The function of the menu (the You do not need to define a CSS style for each sub-menu. The position of the sub-menus is automatic (and explained in the CSS section below.) The HTMLThe complete HTML is in the source file. ...
<body onload="initialiseMenu();">
<h1>DMenu: Sample Simple</h1>
<ul id="mainmenu">
<li><a href="about/">About Us</a></li>
<li><a href="about/">Articles</a>
<ul>
<li><a href="articles/">C#</a>
<ul>
<li><a href="articles/">C# Reference</a></li>
<li><a href="articles/">Tutorials</a></li>
<li><a href="articles/">Samples</a></li>
<li><a href="articles/">FAQ</a></li>
</ul>
</li>...
...</ul>
</li>
<li><a href="about/">Tools</a>
<ul>
<li><a href="articles/">Assemblers</a></li>
<li><a href="articles/">Disassemblers</a></li>
<li><a href="articles/">CP Utilities</a>
</ul>
</li>
<li><a href="contactus/">Contact Us</a></li>
</ul>
...
As you can see it looks just like a normal According to the W3C the proper way to nest lists is as above, e.g. the sub-UL is within the LI element and not outside of it. This is critical also for the JavaScript to work properly (i.e. if you don't nest the lists properly then the JavaScript will not work.) The only setup note you need to know about really is the The JavaScriptThe HTML is dead simple and nothing new. But the JavaScript is quite fun and interesting. I am going to step through it line by line: function showSubMenu(){
var objThis = this;
for(var i = 0; i < objThis.childNodes.length; i++)
{
if(objThis.childNodes.item(i).nodeName == "UL")
{
objThis.childNodes.item(i).style.display = "block";
break;
}
}
}
Very simply this is the method that is called on mouse over of an At this point you have On an aside the function hideSubMenu()
{
var objThis = this;
for(var i = 0; i < objThis.childNodes.length; i++)
{
if(objThis.childNodes.item(i).nodeName == "UL")
{
objThis.childNodes.item(i).style.display = "none";
break;
}
}
}
Virtually identical to the function initialiseMenu()
{
var objLICollection = document.body.getElementsByTagName("LI");
for(var i = 0; i < objLICollection.length; i++)
{
var objLI = objLICollection[i];
for(var j = 0; j < objLI.childNodes.length; j++)
{
if(objLI.childNodes.item(j).nodeName == "UL")
{
objLI.onmouseover=showSubMenu;
objLI.onmouseout=hideSubMenu;
for(var j = 0; j < objLI.childNodes.length; j++)
{
if(objLI.childNodes.item(j).nodeName == "A")
{
objLI.childNodes.item(j).className = "hassubmenu";
}
}
}
}
}
}
First it gets a complete collection of all Next the code loops through the collection by getting the length of the collection For each node in the collection it then loops through it's child elements looking for a If one is found it assigns the The last thing to do is to once again loop through the child elements and assign the The CSSThe CSS is short but sometimes tricky. I will step through each relevant class: ...
ul, li
{
font-size: small;
margin-top: 0px;
margin-right: 0px;
margin-bottom: 0px;
display: block;
}
...
Just give all ...
ul
{
width: 130px;
border: solid 1px #333333;
border-top: solid 5px #333333;
border-right: solid 2px #333333;
}
...
Give all ...
ul li ul
{
display: none;
position: absolute;
}
...
...
li a
{
padding: 2px;
text-decoration: none;
color: #000000;
background-color: #ffffee;
width: 100%;
display: block;
border-bottom: dashed 1px #333333;
text-indent: 2px;
font-size: small;
}
...
Most of this is dedicated to making the menu items look nice. e.g. the dashed bottom border, the background colour etc. Once again a parent/child selector is used: The only important part is the Also the ...
li a:hover
{
background-color: #ffcc00;
font-weight: bold;
border-bottom: solid 1px #333333;
}
...
This just defines the style of the ...
li
{
float: left;
width: 98%;
}
...
This one seems simple, but is critical.
We are almost at the end. ...
a.hassubmenu
{
background-image: url(../img/lay_dmnuhassub.gif);
background-repeat: no-repeat;
background-position: 120px 7px;
}
...
Remember the All it really does is display the lay_dmnuhassub.gif graphic in the background of the element.
Possible Improvements & Bugs
ConclusionAnd that folks is a wrap. All in all quite simple and a very elegant solution to producing DHTML menus. For now the DHTML menu is perfect for a forwards thinking website content with not having a DHTML menu on older browsers or on company intranets where you can control what browser users use. In the future with the above tweaks this kind of web code is going to become more and more popular. Overall though the concept I am driving at is seperation of structure/content, presentation/style and function. This is critical to grasp for the web to move forward and in creating efficient development and maintenance teams. Without it we remain with our hard to maintain and non-forwards-compatible websites. | ||||||||||||||||||||