Pop-Up Menus
  Building a Menu

The create() method will build the elements of a menu and add them to the page. It can only be called once for each menu, and once it's called, you cannot add items or submenus to it or change the appearance.

create() should only be called after the page has finished loading. The easiest way to do this it so set up a function to call via the onload event in the <BODY> tag. Here is a typical page setup.

  <html>
  <head>
  <title></title>
  <script language="JavaScript" src="dhtmllib.js"></script>
  <script language="JavaScript" src="popupmenu.js"></script>
  <script language="JavaScript">

  // Define menus.

  var myMainmenu = new PopUpMenu(120);
  var mySubmenu1 = new PopUpMenu(100);
  var mySubmenu2 = new PopUpMenu(100);

  /* ... see above for details ... */

  function init() {

    // Create the menus.

    myMenu.create();
  }

  </script>
  </head>
  <body onload="init()">

  <a href="#" onclick="myMainmenu.open(); return false">Menu</a>
  <!-- your page contents -->

  </body>
  </html>

Note that you do not need to call the create() method for submenus, they are built automatically when the top-level menu is created.

Displaying a Menu

Once built, you can then display the menu in one of several ways, depending on how you want it to behave. The open() method is used to display a menu. You can set this up however you want. Here a link is used to show a menu when clicked.

Menu 1

The HTML code looks like this.

  <a href="#" onclick="menu1.open(); return false">Menu</a>

You can optionally pass x and y coordinates to open() to specify the exact position you want the menu to appear at. If none are given, the menu will appear under the current mouse position as demonstrated above.

It should be noted that some older versions of Netscape require a function to be called with the same number of arguments that it is defined with. To prevent errors on these browsers, use null values for the optional arguments.

  <a href="#" onclick="menu1.open(null, null); return false">Menu</a>

By default, a menu will disappear when the mouse is moved off the menu and any submenus it may have. For top-level menus (that is, a menu that was not defined as a submenu) you can change this behavior so that it stays displayed.

Click the link below and another menu will appear at left. This menu is set up so that it stays in a given spot on the page and does not disappear when moused off.

Open Menu 2

Here the HTML code looks like this.

  <a href="#" onclick="menu2.open(40, 1300); return false">Menu</a>

You make a menu static using the setStatic() method, passing it either true or false to turn it on or off. This is useful if you want to keep a persistent navigation menu displayed on a page. Submenus will appear and disappear as before.

You can explicitly close a static menu with the close() method.

Close Menu 2

And here's the HTML code.

  <a href="#" onclick="menu2.close(); return false">Menu</a>

Additional Methods

Other methods are provided to help position menus. These are valid only for top-level menus.

  • moveTo(x, y) - Moves a menu to the given coordinates. This allows you to position static menus anywhere on the page.

  • moveBy(dx, dy) - Similar to moveTo() but moves the menu relative to its current position.

  • getzIndex() - Returns the current zIndex value of the menu.

  • setzIndex(z) - Sets the zIndex value of the menu. Any submenus are given the same value. This allows you to set the stacking order when two menu sets overlap.

Using Menus in Frames

You can create menus within framed pages and manipulate them from other frames using standard JavaScript methods. Keep in mind, however, that there are limitations on what you can do with the menus when using frames.

Frames are treated as individual windows by the browser. Menus cannot cross over the boundaries between frames, any more than an image on a page can be made to stick outside of the browser window. Likewise, you cannot have a submenu appear in a frame other than the one containing its parent menu.

You can, however, achieve a similar effect with some cross-frame coding and clever positioning. An example is provided to demonstrate some techniques you can use.

How It Works

When a PopUpMenu object is defined, the width is set according to the size given and the remaining properties are set to default values. These can be changed via the provided methods which simply update those properties.

The constructor also defines an empty array for storing the menu's items along with some other properties which will be used later to control the menu. Then it assigns functions to the object's methods.

The constructor for a PopUpMenuItem sets the item text and link strings according to the values given. It also creates a subMenu property that will be used to store a pointer to a PopUpMenu if one is assigned to the item as a submenu.

Layer Layout

When the create() method is called for a menu, several layers are dynamically built and added to the page for it. First a base layer is created to contain all the other layers. By nesting the other layers within this base the entire menu can be positioned, hidden and made visible as a single entity.

The layers for the border are added first. To achieve a beveled look, pairs of layers are created, one set to the border highlight color and one set to the border shadow color. The second of each pair is clipped by one pixel on the top and left to allow the first layer to show through as a thin line along those edges.

The thicker the border, the more pairs are needed. Each pair is made progressively smaller by one pixel on each side so when stacked the final effect is a smooth diagonal at the upper-right and lower-left corners. The figure below exaggerates the size differences to demonstrate.

After the bevel layers come the item and separator layers. Separators are a special type of item with no text or link. They consist of a single layer with a two row table that uses background colors and the transparent gif image to give the bar it's appearance.

Each text item however, is made up of three stacked layers of equal size positioned directly on top of each other. The bottom layer contains the item text and uses the normal item colors specified for the menu. The next layer also has the item text but with is set with the menu's highlighted item colors. The top layer is empty and transparent. It will be used to capture mouse events for that item.

All the item and separator layers must be created before any can be positioned within the menu. This is because the height of each item will vary depending on the size of the item font and whether or not the text must wrap onto additional lines to fit within the allowed width.

Page 1 - Page 2 - Page 3


Home