DHTML Lab: Hierarchical Menus, I; Menu Setup | WebReference

DHTML Lab: Hierarchical Menus, I; Menu Setup


Logo

DHTML Hierarchical Menus, Part I
menu creation and setup

Webreference

Contents

Open the menus above to remind yourself that this is a technique worth learning.

Creating the Menu and Item Elements

Both menus and items are created by makeElement():

function makeElement(whichEl,whichContainer) {
  if (arguments.length==1) whichContainer = window;
  eval(whichEl + "= new Layer(menuWidth,whichContainer)");
  return eval(whichEl);
}

Recall that makeElement() received a single argument when called for menu creation and two arguments for item creation. Our positioned elements are created on-the-fly using the Navigator new Layer() constructor. See column 10, Navigator Jigsaw Puzzle, for a detailed discussion. Suffice to say that it accepts up to two arguments. A mandatory first, integer, argument specifies the wrapping width of the new element. The second, optional argument, specifies the parent element of the new element. That is, the element that contains the new element.

Menus have no containing element. They are contained in the window object. Items are contained in menus. For the first time, in these columns, we use the arguments property of functions. arguments has only one property of its own, length, storing the number of arguments passed to the function. Using this property we can direct our functions to execute different statements depending on the number of arguments received. In our case, we check for a second argument. If none is found, we in effect create a second argument by assigning window to the whichContainer variable. Using the global menuWidth variable and the new whichContainer variable, we create a new positioned element. By using eval(), we create element references out of the element name strings passed as first arguments(whichEl). For example, if whichEl is the "elMenu1" string, makeExample() creates an element with a variable reference of elMenu1. This reference is then returned to the calling function (eg. makeTop()) to be used as an identifier.

Menu Setup

The menuSetup() function, a method of all menu elements, can have up to four arguments, the first two being mandatory. Top level menus pass only the first two, that is, hasParent and lastItem. (see previous page) Child menus pass two additional arguments, openCont and openItem, which designate the parent menu and parent item of the child. Since menuSetup() is a method of menu elements, the this keyword is used to refer to the calling element:

function menuSetup(hasParent,lastItem,openCont,openItem) {
  this.menuOut = menuOut;
  this.menuOver = menuOver;
  this.onmouseover = this.menuOver;
  this.onmouseout = this.menuOut;
    
  this.showIt = showIt;
  this.keepInWindow = keepInWindow;
  this.hideTree = hideTree
  this.hideParents = hideParents;
  this.hideChildren = hideChildren;
  this.hideTop = hideTop;
  this.hasChildVisible = false;
  this.isOn = false;
  this.hideTimer = null;
  
  this.fullHeight = lastItem.top + lastItem.document.height;
  this.clip.bottom = this.fullHeight;
  if (hasParent) {
    this.hasParent = true;
    this.parentMenu = openCont;
    this.parentItem = openItem;
    this.parentItem.child = this;
  }
  else {
    this.hasParent = false;
    this.hideSelf = hideSelf;
  }
}

During the setup process, the menu element will be assigned properties, and more methods that use functions. We will go through the setup line-by-line, then look at the functions assigned to the new methods.

  this.menuOver = menuOver;
  this.menuOut = menuOut;
  this.onmouseover = this.menuOver;
  this.onmouseout = this.menuOut;

The menuOver() and menuOut() functions are assigned to the menuOver and menuOut methods of the menu. These methods are then assigned to the mouseover and mouseout event handlers of the menu. This technique assures that when the events occur the handler methods/functions immediately identify which elements called them.

  this.showIt = showIt;
  this.keepInWindow = keepInWindow;
  this.hideTree = hideTree
  this.hideParents = hideParents;
  this.hideChildren = hideChildren;
  this.hideTop = hideTop;

Six more functions are assigned to methods:

      showIt() - toggles visibility;
keepInWindow() - prevents menu from appearing off-screen;
    hideTree() - hides all parents/children in a menu tree;
 hideParents() - hides all parents in a menu tree;
hideChildren() - hides children in a menu tree;
     hideTop() - hides top level menu in a menu tree;

Next, three properties are initialized:

  this.hasChildVisible = false;
  this.isOn = false;
  this.hideTimer = null;

The first, hasChildVisible is a Boolean that tracks whether any of the menu items have opened a child menu.

isOn tracks whether the menu is visible and whether it is part of the current tree.

hideTimer will store any timer variable that may be used later in timed hiding. Only top level menus will get a timer. Child menus will retain the null value for this property.

Since menuSetup() is called after all contained items have been created and positioned, it is given a property to reflect the vertical height of all the items, then it is clipped to that height:

  this.fullHeight = lastItem.top + lastItem.document.height;
  this.clip.bottom = this.fullHeight;

Finally, the first passed argument is used. If the menu is a child menu, the first argument (hasParent) is true. In this case, a new property, hasParent is created to reflect this, and two other properties, parentMenu and parentItem store the menu and item elements that open the child menu. Finally, the child menu itself is assigned to the child property of its own parent item.

  if (hasParent) {
    this.hasParent = true;
    this.parentMenu = openCont;
    this.parentItem = openItem;
    this.parentItem.child = this;
  }
  else {
    this.hasParent = false;
    this.hideSelf = hideSelf;
  } 

If the menu is top level, the hasParent property is set to false and the hideSelf() function is assigned to the menu's hideSelf method.

Are We Confused Yet?

Don't be. Once all our methods have been defined, and all the functions discussed, you will see how the actual execution and menu navigation become elementary to establish and follow. It is not necessary at this stage to know what each method does or what statements the functions contain. We've looked under the Christmas tree, found presents marked for distribution and we are distributing them. Once that is done, we will open them and find that all the parts of a train set are there and that they fit together nicely.

For now, let's look at the function that sets up the individual items.


Produced by Peter Belesis and

All Rights Reserved. Legal Notices.
Created: Feb. 19, 1998
Revised: Feb. 19, 1998

URL: http://www.webreference.com/dhtml/column14/menuSetup.html