Web DevCenter
oreilly.comSafari Books Online.Conferences.
MySQL Conference and Expo April 14-17, 2008, Santa Clara, CA

Sponsored Developer Resources

Web Columns
Adobe GoLive
Essential JavaScript
Megnut

Web Topics
All Articles
Browsers
ColdFusion
CSS
Database
Flash
Graphics
HTML/XHTML/DHTML
Scripting Languages
Tools
Weblogs

Atom 1.0 Feed RSS 1.0 Feed RSS 2.0 Feed

Learning Lab






Designing with Javascript.

Hierarchical Menus with the Underrated style.display Object

by Bill Pena, coauthor of Designing with JavaScript, 2nd Edition
02/22/2002

One of the most common DHTML requests I get is for a Windows Explorer-style hierarchical menu, where there's a list of topics or "folders" that a user can click on to reveal subtopics, or "files," within that folder. It's a common desktop metaphor that seems ever more necessary on the Web, especially as we see navigation bars incorporating larger and more complex content while still trying to fit on the screen. Hierarchical menus are a solution to the common problem of having too many links in too small a space.

But, I figured, there are several Web sites where you can find large, complex scripts to create large, complex hierarchical menus. Instead, I'll show you how to make your own menus, of any length or complexity, with the use of an extremely useful and widely unknown DOM CSS property, style.display.visibility. Most DHTML coders know this as the default CSS property, used to show and hide a layer; it's a pain to use when the visibility of a layer affects the position of other layers because visibility only affects whether an HTML element is visible to the user, and not whether the element is rendered on the page.

When you set an element to visibility="hidden", it simply disappears while still taking up space on the page, almost as if it were transparent. However, if by hiding an element you intend to have another one move up and fill the empty space, like you would expect if you close a folder in a menu, you would have to explicitly reposition each element that is affected by hiding that first element, which is a very tedious task. display lets you show and hide an element as well, but rather than just making it transparent, like visibility does, it completely pulls the element from the page, so the Web browser will render and display the page as if the element didn't exist, filling in gaps and all. It seems like a subtle difference, but it makes a huge difference in scripting time and complexity.

Unfortunately, not every browser supports the style.display object. Only Netscape 6 and IE5.5 and above support this object, but as a standard CSS2 property, other browser makers are working toward their own support. So before you go ahead and use this object in your scripts, make sure you start your script by using browser detection to redirect users with non-compliant browsers. To learn more about browser detection, check out Chapter 6, "Too Many Browsers? Not Really," in Designing with JavaScript.

Houdini with an index

With a little clever design, we can build ourselves a standard, left-hand navigation bar that we can make dynamic with only a few lines of JavaScript. The secret is understanding how layers and tables act like containers for content, and how they automatically resize themselves to fit the content they contain. If you've spent much time designing Web sites, you've noticed how important the content in a table is to the size of the table; the "transparent, one-pixel GIF" hack developed as Web designers realized that some browsers would ignore specified widths and heights of tables if the content of the table didn't fill the entire space.

We can now use this property of content containers to our advantage, nesting tables and layers that will automatically resize to create our hierarchical menu. In a nutshell, we'll create a layer that lists a couple of topic areas, "Projects" and "Interests," from my Web site. The layer also contains tables, which contain sub-listings of each area, that are initially set to style.display="none" with JavaScript. This causes the Web browser to only display the two topic links, making the containing layer take up only the height necessary to list those links.

If we change the display value of a table with JavaScript once the page has loaded, the containing layer will resize to incorporate the table, and the links will appear as if from nowhere. Voila! That's the basis of our menus, and many other DHTML tricks! This simple manipulation of one DOM CSS object, in this case style.display, combined with a little ingenuity lets you do some pretty wonderful things.

Let's take a look now at the menu we'll be creating, so you can get a better picture of how this fits together:

Screen Shot.

As you can see, first we have a layer with two links, "Projects" and "Interests." When "Projects" is clicked, the menu expands and displays a list of sublinks below "Projects." In HTML, the layout is quite simple, but by adding id attributes in the right places, we give ourselves the power to display and hide these links individually with JavaScript:

<div>
	Projects
	<table id="projectlinks">
		Designing with JavaScript
		Hypercubes
		...
	</table>
	Interests
	<table id="interestlinks">
		...
	</table>
</div>

We can extend this menu another level just as easily, and show chapters below the "Designing with JavaScript" link, by nesting another table:

<div>
	Projects
	<table id="projectlinks">
		Designing with JavaScript
		<table id="chapters">
			Chapter 1
			Chapter 2
			Chapter 3
			...
		</table>
		Hypercubes
		...
	</table>
	...
</div>

And we get this:

Screen shot.


Pages: 1, 2

Next Pagearrow