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.
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.