Creating Drop-Down Menus

Drop-down menus have been a favorite GUI device for years. The menu header appears as a single word or phrase at the top of the window or screen, and when clicked it reveals a list of further options. In a File menu, for example, you might find Save, Close, and Print.

Now you can achieve the same effect on the Web with DHTML. As with most drop-down menu systems, this Web-based version lets you mouse over a menu header to show the menu immediately underneath it (Figures 23.4 and 23.5). You can place anything you want in these menus, not just links, but also forms, images, or other content.

Figure 23.4. The menu headers.

Figure 23.5. When a menu header is rolled over, the rollover effect turns the background red and displays the menu underneath.

To add drop-down menus:


var objNavMenu = null;

Initialize the global variables you'll be using (Code 23.2). One variable you'll need to pay special attention to is the number of drop menus (numDropMenu), which records the total number of menus on the page. You can also set the colors used for the rollovers.

Code 23.2. The initDropMenu() function sets up the global event handlers for the menus; showDropMen() is responsible for positioning and displaying the menu; and hideDropMenu() will make it vanish when no longer needed.

[View full width]

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" " xhtml1- strict.dtd"> <html xmlns=""> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>CSS, DHTML &amp; Ajax | Drop-down Menu</title> <script type="text/javascript"> <! var objNavMenu = null; var prevObjNavMenu = null; var prevObjDropMenu = null; var numDropMenu = 3; // link styles var bgLinkColor = '#000'; var bgLinkHover = '#f00' var bgLinkActive = '#900' var linkColor = '#fff' var linkHover = '#fff' var linkActive = '#fff' var isIE = null; if (navigator.appName.indexOf('Microsoft Internet Explorer') != -1) isIE=1; function initDropMenu () {      document.onclick = hideDropMenu;      for (i=1; i<=numDropMenu; i++) {          menuName = 'dropMenu' + i;          navName = 'navMenu' + i;          objDropMenu = document.getElementById(menuName);          objNavMenu = document.getElementById(navName); = 'hidden';          objNavMenu.onmouseover = showDropMenu;          objNavMenu.onmouseout = menuOut;          objNavMenu.onclick = showDropMenu;       }       objNavMenu = null;       return; } function showDropMenu(e) {       menuName = 'drop' +,;       objDropMenu = document.getElementById(menuName);       if (prevObjDropMenu == objDropMenu) {              hideDropMenu();          return; } if (prevObjDropMenu != null) hideDropMenu(); objNavMenu = document.getElementById(; if ((prevObjNavMenu != objNavMenu ) || (prevObjDropMenu == null)) { = linkActive; = bgLinkActive; } if (objDropMenu) {     xPos = objNavMenu.offsetParent. offsetLeft + objNavMenu.offsetLeft;     yPos = objNavMenu.offsetParent. offsetTop + objNavMenu.offsetParent. offsetHeight;     if (isIE) {        yPos -= 1;        xPos -= 6;     } = xPos + 'px'; = yPos + 'px'; = 'visible';     prevObjDropMenu = objDropMenu;     prevObjNavMenu = objNavMenu;   } ; } function hideDropMenu() {      document.onclick = null;      if (prevObjDropMenu) { = 'hidden';          prevObjDropMenu = null; = linkColor; = bgLinkColor;      }      objNavMenu = null; } window.onload=initDropMenu; // --> </script> <style type="text/css" media="screen"> body { url(alice23.gif) no-repeat 0px 8px; } h1 {      font:small-caps bold italic 2.5em Georgia, 'Times New Roman', times, serif;      color: red; } h2 {      color:#999; } .page {      position: relative;      top: 190px;      left: 165px;      width: 480px; } #menuBar {      display: block;      margin-bottom: 5px;      position: relative;      top: 0px;      left: 0px;      right: 0px;      width: 99%;      overflow: hidden;      background-color: #000; } .menuHeader {      color: #fff;      font-size: 12px;      font-family: arial, Helvetica, sans-serif;      font-weight: bold;      text-decoration: none;      white-space: nowrap;      cursor: pointer;      padding: 5px;      margin: 0px;      padding-right: 15px;      display: inline;      position: relative;      background-color: #000;      border-right: 1px solid #000000; } .menuDrop {      position: absolute;      visibility: hidden;      z-index: 1000;      top: 60px;      left: 0;      width: 175px;      height: auto;      margin: 0;      padding: 0;      color: #999999;      font-size: 12px;      font-family: arial, Helvetica, sans-serif;      background-color: #ffffff;      background-repeat: repeat;      border-style: solid;      border-width: 0 1px 1px;      border-color: #003365; } .menuDrop a {      display: block;      text-align: left;      padding: 2px 5px;      border-top: 1px solid #ccc;      text-decoration: none; } .menuDrop a:link {      color: #f00; } .menuDrop a:visited {      color: #f00; } .menuDrop a:hover {      color: #fff;      background-color: #f00; } .menuDrop a:active {      color: #ffffff;      background-color: #c00; } </style> </head> <body> <div >      <div  >Part I</div>      <div  >Part II</div>      <div  >Part III</div></div> <div  > <a href="ch01.html">Down The Rabbit- Hole</a><a href="ch02.html">The Pool of Tears</a><a  href="ch03.html">A Caucus- Race and a Long Tale</a><a href= "ch04.html">The Rabbit Sends in  a Little Bill</a> </div> <div  > <a href="ch05.html" onfocus="if (this.blur) this.blur();">Advice from a Caterpillar</a> <a  href="ch06.html">Pig and Pepper</a> <a href="ch07.html">A Mad Tea-Party</a> </div> <div  > <a href="ch08.html">The Queen's Croquet- Ground</a><a href="ch09.html">The Mock Turtle's  Story</a><a href="ch10.html">The Lobster Quadrille</a><a href="ch11.html"> Who Stole The  Tarts?</a><a href= "ch12.html">Alice's Evidence</a> </div> <div > <h1>ALICE'S ADVENTURES IN WONDERLAND</h1> Lewis Carroll <h2>THE MILLENNIUM FULCRUM EDITION 3.0</h2> </div> </body></html>

Because of some slight positioning differences between Internet Explorer and other browsers, we're also going to have to determine whether the code is being run in Internet Explorer.


function initDropMenu ()

Add the function initDropMenu() to your JavaScript. This function sets a global event handler to hide any visible menus whenever the visitor clicks the screen.

The function then uses the variable numDropMenu set from Step 1 to cycle through each menu header (objNavMenu) and menu (objDropMenu) to hide the menus and set how menu headers and menus should behave when moused over, moused out, and clicked. The important event to watch is the one that triggers the initial opening of the menu:

objNavMenu.onmouseover = showDropMenu;

If you want to change the behavior so that the menu opens only when the header is clicked, change onmouseover to onclick.


function menuOut(e) {…}

Add the function menuOut() to your JavaScript.

This function reinstates the global menu-hiding onclick event handler when visitors moves their mouse cursor out of a menu header. It also sets the menu header back to its normal style (gray background with black text).


function showDropMenu(e) {…}

Add the function showDropMenu() to your JavaScript.

This function is triggered when the visitor clicks a menu header. It first hides the menu currently showing (prevObjDropMenu) using the hideDropMenu() function you'll add in Step 6. It then sets the style for the menu header option so that it looks selected (white text on a black background), and positions and shows the appropriate menu. Notice that we use the isIE variable from Step 1 to tweak the positioning slightly for Internet Explorer.


function hideDropMenu() {…}

Add the function hideDropMenu() to your JavaScript.

This function disables the global onclick event and then hides any menus that are showing and sets the menu header style to its normal state (gray background with black text).



In the JavaScript, add an onload event handler to trigger the initDropMenu() function when the page loads.


body {…}

Add styles for the body of your Web page to set the margins and padding. One thing that will greatly equalize the positioning of elements between the different browsers is to set the padding and margins for the body to 0. There will still be some discrepancy, but not nearly as much.


#menuBar {…}

Set up a CSS rule for the menu bar, which will hold the menu headers. Beyond using relative positioning, the exact style is up to you.


.menuHeader {…}

Set up a class to define the appearance of the menu headers. Remember, rather than links (<a>) we'll be setting these up using <div> tags.

This class will set the initial appearance of the menu headers, which are then changed by the JavaScript depending on the current :hover state. Make sure to use relative positioning, but the rest of the styles are up to you.


.menuDrop {…}

Set up a class to define the drop-down menu's appearance. Make sure to use absolute positioning, set the z-index above all other layers, and set the visibility to hidden.


.menuDrop a {…}

Set up the style for the drop-down menu links that are children of the .menuDrop class, setting each of the link pseudo-classes (:link, :visited, :hover, and :active).


<div >…</div>

Set up the menu bar object using a <div> element and the menuBar ID.


<div >…</div>

Inside the menu bar object, use <div> elements and the menuHeader class to add a menu header for each menu. You can add as many menu headers as you want, but make sure that each one has a unique navMenu ID (navMenu1, navMenu2, navMenu3, and so on). Remember to set the variable numMenus in Step 1 to the number of menus you create here.


<div  >…</div>

For each menu header you created in Step 14, you should now create the menu to go under it, using <div> elements and the menuDrop class. These menus are absolutely positioned, so the code can come anywhere in the HTML. However, make sure that each has a unique dropMenu ID (dropMenu1, dropMenu2, dropMenu3, and so on).


  • This particular menu works much like a standard operating system menu, in that the menu does not pop up until visitors click the menu head, but it then disappears when they click another menu header, one of the options in the menu, or anywhere else on the page.

  • To improve accessibility on your Web site for users who may not be running JavaScript, consider adding accessibility controls to your links. See the sidebar "Using Access Keys to Improve Accessibility" for more details.

Using Access Keys to Improve Accessibility

Although most people coming to your Web site will be using their mouse to control what's going on, there are many potential visitors who, for a variety of reasons, may not be able to use a mouse as effectively or at all. To accommodate visitors who are using a keyboard or speech-recognition system to navigate the Web, you can include the accesskey attribute for important links:

<a href="index.html" _accesskey="h">Home</a>

Whenever visitors press the H key, this link will receive focus, so that they can then press (or speak) Return to access the page.

CSS, DHTML and Ajax. Visual QuickStart Guide
CSS, DHTML, and Ajax, Fourth Edition
ISBN: 032144325X
EAN: 2147483647
Year: 2006
Pages: 230 © 2008-2017.
If you may any questions please contact us: