DHTML Lab: Hierarchical Menus Version 3 | 17 | WebReference

DHTML Lab: Hierarchical Menus Version 3 | 17


Hierarchical Menus: Version 3
assigning tree-specific parameters / element 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 = 20;
childOffset = 5;
perCentOver = null;
secondsVisible = .5;
fntCol = "white";
fntSiz = 10;
fntBold = true;
fntItal = false;
fntFam = "sans-serif";
backCol = "black";
overCol = "#AAAAAA";
overFnt = "white";
borWid = 0;
borCol = "black";
borSty = "solid";
itemPad = 3;
imgSrc = "triW.gif";
imgSiz = 11;
separator = 0;
separatorCol = "";
isFrames = false;
keepHilite = true; 
NSfontOver = false;
clickStart = true;
clickKill = true;
showVisited = "";

Background Reading:

  column 14
  column 15
  column 18
  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.


This function is common to both browsers and, for the most part, sets tree-specific properties. Every menu has ten new properties, the values of which are the same for all menus in the tree. These are:

  • menuWidth - the width of all menus in the tree
  • menuLeft - the original x-position of the menu tree
  • menuTop - the original y-position of the menu tree
  • menuFontColor - the font color of all menus in the tree
  • menuFontOver - the mouseover font color of all menus in the tree
  • menuBGColor - the background color of all menus in the tree
  • menuBGOver - the mouseover background color of all menus in the tree
  • menuBorCol - the border color of all menus in the tree
  • menuSeparatorCol - the separator color of all menus in the tree
  • treeParent - the top-level menu in the tree

The first nine correspond to the nine tree-specific parameters set in the top-level array. The function checks the array element for a value. If a value is found (i.e. if not null or empty string), it is assigned to the property. If no value exists, the default parameter variable value is assigned. In the case of menuLeft and menuTop, where no defaults exist, the array element value is assigned directly.

function setMenuTree(isChild,parMenu) {
  if (!isChild) {
    this.menuWidth = this.array[0] ? this.array[0] : menuWidth;
    this.menuLeft = this.array[1];
    this.menuTop = this.array[2];
    this.menuFontColor = this.array[3] ? this.array[3] : fntCol;
    this.menuFontOver = this.array[4] ? this.array[4] : overFnt;
    this.menuBGColor = this.array[5] ? this.array[5] : backCol;
    this.menuBGOver = this.array[6] ? this.array[6] : overCol;
    this.menuBorCol = this.array[7] ? this.array[7] : borCol;
    this.menuSeparatorCol = this.array[8] ? this.array[8] : separatorCol;
    this.treeParent = this;
    this.startChild = this;
  else {
    this.menuWidth = parMenu.menuWidth;
    this.menuLeft = parMenu.menuLeft;
    this.menuTop = parMenu.menuTop;
    this.menuFontColor = parMenu.menuFontColor;
    this.menuFontOver = parMenu.menuFontOver;
    this.menuBGColor = parMenu.menuBGColor;
    this.menuBGOver = parMenu.menuBGOver;
    this.menuBorCol = parMenu.menuBorCol;
    this.menuSeparatorCol = parMenu.menuSeparatorCol;
    this.treeParent = parMenu.treeParent;
  this.maxItems = (isChild) ?
[cc]   this.array.length/3 : (this.array.length-9)/3;
  this.hasParent = isChild;
  this.setup = menuSetup;
  this.itemCount = 0;

In version 3 we can display our menu tree from any level of the hierarchy. We therefore need to keep track of the level we begin at, since the mouseout "hide" timer delays the hiding of the first menu displayed. In version 2, this was always the top-level menu. In version 3, every top-level menu has a startChild property which stores the menu that you want to display as the first one in the hierarchy. Its original value is the top-level menu. Later, depending on the value of the argument in the in-page link, this property's value will change. In order to give access to this property from all child menus, the treeParent property stores the top-level menu.

Once the values have been assigned to the top-level menu properties, every child menu created gets the same values assigned to its own properties, keeping a standard across the tree.

The value of the old maxItems property, which stores the number of menu items defined in each array, is determined differently for top-level menus and child menus. For child menus we simply divide the total array elements by three, as before. For top-level menus, we subtract 9 (the parameter elements) from the total elements, and then divide by three.

The last three statements existed in version 2, as well. The hasParent property declaration has been moved up to this function, from menuSetup(), to allow us to identify child menus earlier. The need for this becomes apparent later.


Recall that makeElement() actually creates the positioned elements for the menus and menu items. In version 3, makeElement():

  1. creates the menu and item elements for NS4 (as before)
  2. creates ONLY the menu element for IE4 (new)
  3. calculates the width necessary for NS4 menu/item creation (new)
  4. returns the created element to the calling statement (as before)
function makeElement(whichEl,whichWidth,whichParent,whichContainer) {
  if (NS4) {
    if (whichWidth!=null) {
      elWidth = whichWidth;
    else {
      elWidth = (whichContainer) ?
[cc]  whichContainer.menuWidth : whichParent.menuWidth;
      if (whichContainer) elWidth = elWidth-(borWid*2)-(itemPad*2);
	if (!whichContainer) whichContainer = menuLoc;
    eval(whichEl + "= new Layer(elWidth,whichContainer)");
  else {
    elStr = "<DIV ID=" + whichEl + " STYLE='position:absolute'></DIV>";
    if (isFrames) eval(whichEl + "= menuLoc." + whichEl);
  return eval(whichEl);

As we saw on the previous page, makeElement() takes up to four arguments for NS4, depending on the menu/item it is creating. For IE4, it takes only one argument. The list below itemizes the argument options for both browsers:

  • top-level menu NS4: two arguments (menu name, width);
  • top-level menu IE4: one argument (menu name);
  • child menu NS4: three arguments (menu name, null, parent menu);
  • child menu IE4: one argument (menu name);
  • any menu item NS4: four arguments (menu name, null, null, containing menu);

When Navigator calls makeElement(), the first task is to determine the width for the element to be created, and assign it to elWidth. If the second argument (whichWidth) is not null, then the element is a top-level menu, and elWidth is assigned the value of whichWidth.

If the second argument is null, then the element is either a child menu or a menu item. If the fourth argument (whichContainer) exists, then the element is an item and elWidth is assigned the value of the item's containing menu menuWidth property. If whichContainer does not exist, then the element is a child menu and elWidth receives the value of the parent menu's menuWidth property. In this way, we assure that all menus in the hierarchy are the same width.

If the element is an item (whichContainer exists), elWidth is adjusted to create the left/right borders and padding surrounding item text, as in version 2.

We now have the relevant width value for creating a new element, but still need to determine the existing element in which the new one will be nested. If the element is not an item (!whichContainer), the element is nested in the window/frame object (menuLoc). If it is an item, it is nested within the containing menu (whichContainer).

Finally, we create the element with new Layer(), as before.

When Explorer calls makeElement(), a new menu element is created, for both top-level and children menus, by simply inserting the HTML for a positioned element within the page's BODY tag (document.body).

The function returns the element created, as before.

On the next page, we'll look at makeMenuIE(), which is the function most affected by the changes in this version.

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/hier3setMenu.html