10.9 Providing Navigation Trail Menus
NN 4, IE 4
10.9.1 Problem
You want the top of every page in a deep
and highly structured site to display "bread crumb
trails" of where the user is within a hierarchy
path.
10.9.2 Solution
Customize and apply the trail.js library (shown
in Example 10-5 in the Discussion) to a location on
your pages where the menu trail is to appear. Figure 10-3 shows one example on a page that includes the
following HTML and script call to the makeTrailMenu(
) function in the library:
<div id="trailMenu" style="position:absolute; left:200px; top:200px">
<script language="JavaScript" type="text/javascript">
document.write(makeTrailMenu( ));
</script>
</div>
10.9.3 Discussion
This recipe assumes that your web documents on the server are
structured in a directory hierarchy that matches the conceptual
organization of the site. For example:
index.html (home at the root directory)
catalog/
index.html (intro to catalog and links to categories)
economy/
[many .html pages for this category]
deluxe/
[many .html pages for this category]
export/
[many .html pages for this category]
support/
index.html (intro to support and links to categories)
contact.html
faq/
downloads/
manuals/
Example 10-5 shows the code for the
trail.js library, which should be linked into
every page of the site that fits within the structural hierarchy.
Example 10-5. The trail.js library
var trailMenu = new Object( );
trailMenu["catalog"] = "Product Line";
trailMenu["economy"] = "Budget";
trailMenu["deluxe"] = "Luxury";
trailMenu["export"] = "Export Only";
trailMenu["support"] = "Product Support";
trailMenu["faq"] = "Frequently Asked Questions";
trailMenu["downloads"] = "Free Downloads";
trailMenu["manuals"] = "Manuals";
function makeTrailMenu( ) {
var parseStart, volDelim, parseEnd;
var output =
"<span style='font-family:Arial, Helvetica, sans-serif; font-size:12px;" +
"color:#000000; padding:4px'>";
var linkStyle = "color:#339966";
var path = location.pathname;
var separator = " » ";
var re = /\\/g;
path = path.replace(re, "/");
var trail = location.protocol + "//" + location.hostname;
var leaves = path.split("/");
if (location.protocol.indexOf("file") != -1) {
parseStart = 1;
volDelim = "/";
} else {
parseStart = 0;
volDelim = "";
}
if (leaves[leaves.length-1] = = "" || leaves[leaves.length-1] = = "index.html" ||
leaves[leaves.length-1] = = "default.html") {
parseEnd = leaves.length -1;
} else {
parseEnd = leaves.length;
}
for (var i = parseStart; i < parseEnd; i++) {
if (i = = parseStart) {
trail += "/" + leaves[i] + volDelim;
output += "<a href='" + trail + "' style='" + linkStyle + "'>";
output += "Home";
} else if (i = = parseEnd - 1) {
output += document.title;
separator = "";
} else {
trail += leaves[i] + "/";
output += "<a href='" + trail + "' style='" + linkStyle + "'>";
output += trailMenu[leaves[i]];
}
output += "</a>" + separator;
}
output += "</span>";
return output;
}
The library begins by defining an object whose string property names
are the various directory names of your site (in any order) and the
corresponding plain language label you want to appear in the menus.
Next is the makeTrailMenu(
) function, which assembles the HTML for
the page's navigation trail menu, based on the path
of the current document and its title. This example uses a guillemet
character (») to act as arrows between
levels.
This trail menu system works best on sites that serve up pages from
.html files because the
location.pathname property contains a lot of the
information that the code uses to generate the menus. You can also
make this work with sites served by server-side programs
(.pl, .asp,
.jsp, .php, and others),
provided the directory structure is preserved. Of course, if you are
using server programming to generate content for pages, you might as
well use that programming power to assemble the menu trail before
ever leaving the server.
The only implementation and maintenance necessities are as follows:
Each page must have a descriptive <title>
tag.
Each directory must have a home page (such as
index.html or default.html)
served up when the URL points to the directory.
Each file must include the trail.js library
containing the data and routines.
Changes or additions made to the site's directory
structure need to be noted in the trailMenu object
definition in the trail.js file.
Employing a custom object (trailMenu) for the
lookup table of directory names and user-friendly labels offers a
much faster way of performing the lookups than a more typical array.
Items do not have to be in any particular order with respect to the
directory structure, but keeping the structures aligned makes it
easier to maintain over time as directories are added, removed, and
renamed.
You have virtually unlimited flexibility in the stylesheet attributes
that affect the appearance of the trail menu. It is also possible to
remove the style sheet from the tag and link it into the page from a
separate .css file if you prefer, provided you
assign an ID or class identifier to the menu container and associate
the container with the imported style rule. Additionally, the menu
can be in the page's body, in a table, or, as shown
in the recipe, a positioned element unto itself.
Slightly more challenging is
implementing this kind of menu within a frameset, where the menu
occupies its own frame and the content that changes is in another
frame. The same algorithms apply, but you have to watch out for two
points in particular. First, you need a way to trigger the rewriting
of the menu each time a content page changes. The way to do this is
through the onload event of each page. It could
invoke a function (loaded into each page from an external
.js library) that assembles the menu (using the
location property of the content window), and
writes the content of the other frame. You also need to modify the
links that surround each clickable item in the menu so that the
target is the content-bearing frame.
In the recipe, the separator between hierarchy levels in the menu
consists of a character that looks like an arrow (a guillemet
character is actually a right-pointing double angle quotation mark).
I would have liked to have used a character that looked more like an
arrow, such as the → or
⇒ entities, but neither is supported by
IE for Windows (through Version 6) or Netscape prior to Version 7
(although they are supported in IE 5 for the Macintosh). But the
separator can be any HTML of your choice, including an image. Simply
assign the HTML to the separator variable.
10.9.4 See Also
Recipe 1.1 for building long strings from bits and pieces; Recipe 14.1 for using document.write( ) while the page
loads.
|