Build a Pop-up Menu Using Dynamic HTML and JavaScript 


Contents

Introduction
Functional Description
The Code
Adapting the Pop-up Menu Code to Your Site
Summary
Download Pop-up Example Code (Popupmnu.zip- 20KB)


Introduction

A pop-up menu using Dynamic HTML and JavaScript can be a key navigational element to effectively provide Web site-wide navigation. For example, pop-up menus used to display a list of articles for each section of a site can help your Web visitors by saving them time and effort in their search for useful information.
At present, the pop-up menu example accompanying this article is visible only to visitors using Microsoft® Internet Explorer 4.0 or higher. People using other browsers or platforms can be sent to a standard table-of-contents page. This article describes how the pop-up menu works, provides all the example code, and discusses considerations necessary to adapt it to your site.


Functional Description

If you have Internet Explorer 4.0 or higher, go to the example at http://www.microsoftfrontpage.com/menuasp/menu.asp and click any navigation item along the left side of the screen. An additional menu box listing the contents of that section appears immediately to the right of the navigational item you selected (and has a nice scroll-down effect). If you move the mouse over one of the article titles in the menu, the title changes color. Clicking the title sends you to an example destination page. The menu remains visible until you click somewhere else on the page.



Figure 1. Screen shot demonstrating the pop-up menu


The Code

How the DHTML pop-up menu works.


Sniffing to Provide the Right Navigation
The navigation menu (the section with the dark blue background) is a table. Each cell in the table is a GIF image. To determine whether to load the images that activate the pop-up menu, we use Active Server Pages (ASP) to sniff for the user's browser and its version. Here is the server-side sniff in JScript:
<% @LANGUAGE="JScript" %>
<%
function BrowserData(sUA) {
var iMSIE = sUA.indexOf("MSIE");
this.userAgent = sUA;
this.browser = (iMSIE > -1) ? "MSIE" : "Other";
this.majorVer = parseInt(sUA.substring(iMSIE + 5, iMSIE + 6));
this.getsMenus = ("MSIE" == this.browser && 4 <= this.majorVer);
}
var oBD = new BrowserData(new String(Request.ServerVariables("HTTP_USER_AGENT")));
%>
And here is the client-side sniff:
<html>
<head>
<base href="http://www.microsoftfrontpage.com/menuasp/menu.asp" fptype="TRUE">
<meta http-equiv="Content-Language" content="en-us">
<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<title>SBN Server Menu Demo</title>
<script LANGUAGE="JavaScript"><!--
function BrowserData(sUA) {
var iMSIE = sUA.indexOf("MSIE");
this.userAgent = sUA;
this.browser = (-1 != iMSIE) ? "MSIE" : "Other";
this.majorVer = parseInt(sUA.substring(iMSIE + 5, iMSIE + 6));
this.getsMenus = ("MSIE" == this.browser && 4 <= this.majorVer);
}
var oBD = new BrowserData(navigator.userAgent);

//--></script>
<%
if (oBD.getsMenus)
{
Response.Write('<SCRIPT SRC="menus.js"></SCRIPT> \n');
Response.Write('<LINK REL="stylesheet" TYPE="text/css" HREF="menus.css"></SCRIPT> \n');
}
%>
</head>
This provides graceful navigation for everyone who visits the site.

Activating the Menu
Now we'll concentrate on the pop-up menu functionality. The ID="idMenuTitle1" attribute is accessed by a script through the global document onclick event-handler:
document.onclick = DoMenu;
The global document onclick event-handler calls the DoMenu() function when the user clicks anywhere on the page. The main function, DoMenu hides any open pop-up menus, determines which menu DIV to access, and starts its display. Here is DoMenu():
function DoMenu()
{
window.event.cancelBubble = true;
var eSrc = window.event.srcElement;
if ("object" == typeof(document.all[sOpenMenuID]))
{
document.all[sOpenMenuID].style.visibility = "hidden";
if (sOpenMenuID == eSrc.id.replace("imgMenuTitle","divMenu"))
{
sOpenMenuID = "";
return false;
}
else
{
sOpenMenuID = "";
}
}
if ("clsMenuTitle" == eSrc.className)
{
window.event.returnValue = false;
sOpenMenuID = eSrc.id.replace("imgMenuTitle","divMenu")
if ("object" == typeof(document.all[sOpenMenuID]))
{
var eMenu = document.all[sOpenMenuID];
iChunk = iChunkStep;
var eTR = eSrc.parentElement.parentElement.parentElement
var eTABLE = eTR.parentElement.parentElement;
if ("right" == sMenuPos)
{
eMenu.style.left = eTABLE.offsetLeft + eSrc.width;
eMenu.style.top = eTABLE.offsetTop + eTR.offsetTop;
}
else
{
eMenu.style.left = eTABLE.offsetLeft + 26;
eMenu.style.top = eTABLE.offsetTop + eTR.offsetTop + eSrc.height;
}
eMenu.style.clip = "rect(0 0 0 0)";
eMenu.style.visibility = "visible";
return window.setTimeout("ShowMenu(" + eMenu.id + ")", iChunkDelay);
}
}
}
The window.event.cancelBubble = true statement prevents the command from "bubbling up". Keep in mind, objects in Dynamic HTML can share event handlers. When an event occurs on a child object, the event can travel up the chain of hierarchy within the page until it encounters an event handler to process the event. This process is called event bubbling. (see Event Bubbling in DHTML Applications )
The var eSrc = window.event.srcElement statement assigns the element that was clicked to the variable eSrc (in a variation of the Dvorak notation, "e" is used to stand for element).
The if (sOpenMenuID = "") conditional statement checks whether another menu on the page is open. If there is, the open menu is closed with the document.all[sOpenMenuID].style.visibility = "hidden" statement.

Selecting Which Menu to Display
The second half of DoMenu(), shown in the previous section, selects and displays the appropriate menu. After prepping the page to display the menu (by closing any open menus), DoMenu() tests whether the clicked element belongs to the class clsMenuTitle. In this case it does (because the Next Generation GIF we're clicking contains a CLASS="clsMenuTitle" attribute).
Once we verify that a pop-up menu is called, we need to figure out what menu to display. To do that, get Menu associated with the Menu Title and make sure it exists. If it does, show the Menu:
sOpenMenuID = eSrc.id.replace("imgMenuTitle","divMenu")
if ("object" == typeof(document.all[sOpenMenuID]))
{
var eMenu = document.all[sOpenMenuID];
iChunk = iChunkStep;

The var eMenu = document.all(sOpenMenuID) statement creates a pointer to the element of the page associated with the variable sOpenMenuID-which now has the value idMenu1. The iChunk = iChunkStep statement assigns a client-side global variable to another global variable used to control the display of the Next Generation menu. A timer is started using the window.setTimeout() method. In this case, the timer is set to wait 15 milliseconds and then call the showMenu() function, which will actually display the menu.

Displaying the Menu
Now finally, the Next Generation menu can be displayed. The menu is simply a <DIV> with an ID that matches the one generated from the sOpenMenuID concatenation (and a class of clsMenu). Each menu item is presented within an anchor pointing to the example URL:
<DIV ID="divMenu1" CLASS="clsMenu">
<A HREF="example.htm">Web Services for PCs</A> <BR />
<A HREF="example.htm">International ASP</A> <BR />
</DIV>


Figure 2. The CSS hover property in action

The style of the pop-up menu is outlined in the style sheet, and the hover property is used to create the menu-item color-change. For more on CSS properties and how to apply them to your HTML documents, see Cascading Style Sheets.
.clsMenuTitle { cursor:hand; }
.clsMenu {
border-left:1px black; border-right:1px black; border-top:1px black; border-bottom:1px black; background-color:#0099CC; position:absolute; visibility:hidden; width:180px; z-index:2; padding-left:5px; font-family:verdana; font-size:8pt; padding-right:1px; padding-top:1px; padding-bottom:1px }
.clsMenu A { text-decoration:none; color:black; }
.clsMenu A:hover { text-decoration:underline; color:#cccccc; }

Adapting the Pop-up Menu Code to Your Site
Although there's a fair amount of code, adapting it to your site is fairly trivial, especially if you include the script and style sheet on each page through ASP include statements. The key is to make sure you have all the script, CSS, and inline attributes in place, and keep the properties and values in sync.
For each menu (or list of links) you wish to include, create a DIV item just like the one outlined in Displaying the Menu. Make sure to use the same CLASS values that we do for the menu titles (clsMenuTitle) and the menus (clsMenu), and to use an incremental numbering system for the related <DIV>s (idMenu1, idMenuTitle1, and so on). Download the sample Dynamic HTML code with helpful comments (available at the top of this page) and peruse it to see what CSS, scripts, and inline attributes are placed where.

Summary
Pop-up menus provide an elegant way to simplify the navigation of complex or data-heavy sites. Users have immediate access to all the articles on a site from a small piece of page real estate. They avoid the annoyance of using the back button repeatedly or scrolling to find the information they seek as well as spend less time waiting for unnecessary pages to load. Your Web site benefits from the reduction in server hits that comes with more efficient use of site navigation. And the menus are attractive, too.
If you want to spend more time learning DHTML, you can start with the following:

http://msdn.microsoft.com/workshop/author/om/doc_object.asp
http://msdn.microsoft.com/workshop/author/behaviors/behaviors_node_entry.asp

This article is for informational purposes only. MICROSOFT MAKES NO WARRANTIES, EXPRESS OR IMPLIED, AS TO THE INFORMATION IN THIS DOCUMENT.

Complying with all applicable copyright laws is the responsibility of the user. Without limiting the rights under copyright, no part of this document may be reproduced, stored in or introduced into a retrieval system, or transmitted in any form or by any means (electronic, mechanical, photocopying, recording, or otherwise), or for any purpose, without the express written permission of Microsoft Corporation.

Microsoft may have patents, patent applications, trademarks, copyrights, or other intellectual property rights covering subject matter in this document. Except as expressly provided in any written license agreement from Microsoft, the furnishing of this document does not give you any license to these patents, trademarks, copyrights, or other intellectual property.

More Resources 

©2002  Microsoft Corporation.  All rights reserved. Terms of Use