DHTML Lab: Hierarchical Menus Version 3 | 11 | WebReference

DHTML Lab: Hierarchical Menus Version 3 | 11


Hierarchical Menus: Version 3
Navigator menu creation


Click the link above to reveal menu. Click anywhere on the page to hide menu.

Parameters used for the menus on this page:

menuVersion = 3;
menuWidth = 120;
childOverlap = 50;
childOffset = 5;
perCentOver = null;
secondsVisible = .5;
fntCol = "blue";
fntSiz = "10";
fntBold = false;
fntItal = false;
fntFam = "sans-serif";
backCol = "#DDDDDD";
overCol = "#FFCCCC";
overFnt = "purple";
borWid = 1;
borCol = "black";
borSty = "solid";
itemPad = 0;
imgSrc = "tri.gif";
imgSiz = 10;
separator = 1;
separatorCol = "red";
isFrames = false;
keepHilite = false; 
NSfontOver = false;
clickStart = true;
clickKill = true;
showVisited = "";

Background Reading:

  column 14
  column 15
  column 18
  column 20

old makeMenu():
  column 20

In script listings, cross-browser code is blue, Navigator-specific code is red, and Explorer code is green.

The [cc] symbol denotes code continuation. The code is part of the preceding line. It is placed on a new line for column formatting considerations only.

There are two differences in the menu-creating makeTop() function from its previous incarnation. First, it calls separate makeMenu functions for the two browsers. This is necessary since, as we'll see further down, the IE menus are created in a completely different manner than in previous versions, and the script now bears little resemblance to its NS counterpart. For this same reason, the IE-specific item positioning statements have been scrapped.

function makeTop(){
    beingCreated = true;
    while(eval("window.arMenu" + topCount)) {
        (NS4) ? makeMenuNS(false,topCount) : makeMenuIE(false,topCount);
    status = (topCount-1) + " Hierarchical Menu Trees Created"
    areCreated = true;
    beingCreated = false;


For Navigator, the way the menus are created and the general logic is unchanged. Each menu has many more properties in this version, however, to allow for the new features, so makeMenuNS() must make allowances for them. We'll discuss the function in detail immediately below.

function makeMenuNS(isChild,menuCount,parMenu,parItem) {
  tempArray = eval("arMenu" + menuCount);
  if (!isChild) {
    tempWidth = tempArray[0] ? tempArray[0] : menuWidth;
    menu = makeElement("elMenu" + menuCount,tempWidth);
  else {
    tempWidth = null;
    menu = makeElement("elMenu" + menuCount,tempWidth,parMenu);
  menu.array = tempArray;
  menu.setMenuTree = setMenuTree;
  while (menu.itemCount < menu.maxItems) {
    status = "Creating Hierarchical Menus: "
[cc]    + menuCount + " / " + menu.itemCount;
    prevItem = (menu.itemCount > 1) ? menu.item : null;
    itemName = "item" + menuCount + "_" + menu.itemCount;

    menu.item = makeElement(itemName,null,null,menu);
    menu.item.prevItem = prevItem;
    menu.item.setup = itemSetup;
    if (menu.item.hasMore) {
      makeMenuNS(true,menuCount + "_" + menu.itemCount,menu,menu.item);
      menu = menu.parentMenu;
  menu.lastItem = menu.item;

As we know, the one argument that Navigator requires when creating a positioned element on-the-fly, is width. In previous versions, the width of all menus and, therefore, of all positioned elements, was the value of menuWidth. In version 3, each menu tree can have its own width, so before we create the menu element, we must determine its width, using the top-level array. We first identify the top-level array and assign it to tempArray.

If the menu is the top-level menu (if isChild is false), we create the tempWidth variable and assign to it the value of the first element of the array (tempArray[0]). If this element has no value, tempWidth gets the value of menuWidth. If the menu is a child menu, the width will be determined by makeElement() so then tempWidth is given a null value.

We then call makeElement() to actually create the positioned element, passing the menu identifier as a string ("elMenu" + menuCount), the width (tempWidth) and, in the case of a child menu, the parent menu (parMenu). Notice that, for a child menu, the second argument (width) is null.

As in previous versions, makeElement() returns the element created, which we assign to menu. Now that the menu is an object we can work with, we begin assigning properties to it. First menu.array is assigned tempArray, creating a permanent assignation as compared to a temporary one, since the value of tempArray will change the next time makeMenuNS() is called.

A new version 3 function, setMenuTree() is assigned to the menu's setMenuTree method. Then we call setMenuTree(), passing the isChild and parMenu variables as arguments. Keep in mind that the parMenu variable exists only if the menu is a child menu, when it is passed as an argument to makeMenuNS(). The first time through makeMenuNS(), for each menu tree, it has no value.

setMenuTree() is discussed immediately below. For now, we must know that when we return from setMenuTree() all the tree-specific properties, arising out of the extra elements of the top-level array, have been assigned. The remainder of the function is the same as the old makeMenu() with one exception. When the time comes to create the item elements, makeElement() is called with four arguments. We know that makeElement() is passed two arguments when it creates a top-level menu (the menu name and its width). When it creates a child menu, it gets three arguments (the menu name, its width, and the parent menu). When it creates an item it is passed four arguments (the menu name, its width, the parent menu, and the item container element). Since the second and third arguments pertain to menus and not items, they get a null value. How this all comes together is elaborated in the makeElement() discussion later.

First, however, let's look at the new setMenuTree() function.

Produced by Peter Belesis and

All Rights Reserved. Legal Notices.
Created: Sept. 03, 1998
Revised: Sept. 03, 1998

URL: http://www.webreference.com/dhtml/column21/hier3makeNS.html