-->
Bookmark and Share

Revenge of the Menu Bar

See the demo page for the finished version of the code.

Scripting the Menu Bar

Be sure to look at the demo page and observe how the buttons and menus work before reading on. Understanding the code will be easier if you first see the menu in action.

The Active Button

Looking at the demo page, you may have noticed that only one button and drop down menu can be active at any given time. To track which button (if any) is currently active, another global variable is defined at the beginning of the script.

var activeButton = null;

This global can then be accessed from anywhere in the code as needed, just like the browser global.

Button Event Handlers

Now to put the buttons and menus together. First, unique IDs need to be assigned to each menu's DIV tag. This will allow them to be easily referenced by name.

<div id="menu1" class="menu">
<a class="menuItem" href="...">Menu 1 Item 1</a>
<a class="menuItem" href="...">Menu 1 Item 2</a>
<a class="menuItem" href="...">Menu 1 Item 3</a>
<a class="menuItem" href="...">Menu 1 Item 4</a>
<div class="menuItemSep"></div>
<a class="menuItem" href="...">Menu 1 Item 5</a>
</div>

In the A tags for the menu buttons, an event handler for the onclick event is defined to call the function buttonClick() with two arguments.

<a class="menuButton"
   href="" 
   onclick="return buttonClick(event, 'menu1');"
>Button 1</a>

The first is the Event object. The second is the ID of the menu to be associated with the button.

The Button onclick Event Handler

This function makes a button active, changing its appearance and displaying the menu associated with it.

function buttonClick(event, menuId) {

  var button;

  // Get the target button element.

  if (browser.isIE)
    button = window.event.srcElement;
  else
    button = event.currentTarget;

The first step is to get the element object representing the button link from the Event object. This varies depending on the browser.

Browser Compatibility

IE doesn't follow the standard event model. It uses a single, global event object named window.event rather than passing an event object to the event handler. Also, the event object in IE uses non-standard property names and methods. So separate code is needed.

See the DOM Event Model for details on events and browser compatibility.

Once found, the link element's .blur() method is called, to remove the dotted outline most browsers display around a link when it is clicked.

  // Blur focus from the link to remove that annoying outline.

  button.blur();

Next, it finds the DIV element corresponding to the button's menu. The first time this function is called for a button, we need to locate the menu DIV using the given ID. Once found, it is saved as a user defined property on the button called menu so it can be easily referenced later.

  // Associate the named menu to this button if not already done.
  // Additionally, initialize menu display.

  if (button.menu == null) {
    button.menu = document.getElementById(menuId);
    if (button.menu.isInitialized == null)
      menuInit(button.menu);
  }

Additionally, menuInit() is called. This function takes care of a few display problems with the menu items, mostly related to sub menus. It's detailed later on.

Next it checks to see if some other button is currently active, using the activeButton global. If so, it deactivates it.

  // Reset the currently active button, if any.

  if (activeButton != null)
    resetButton(activeButton);

It then it makes this button the active one (unless it was the active button, in which case we leave it deactivated).

  // Activate this button, unless it was the currently active one.

  if (button != activeButton) {
    depressButton(button);
    activeButton = button;
  }
  else
    activeButton = null;

  return false;
}

The last line returns a value of false, to prevent the browser from attempting to follow the link.

The depressButton() and resetButton() functions do the actual work of changing the button appearance and showing or hiding its menu.