Mega Code Archive

 
Categories / JavaScript DHTML / GUI Components
 

Drop-Down Menus

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"    "http://www.w3.org/tr/xhtml1/DTD/xhtml1-transitional.dtd"> <!--       Example File From "JavaScript and DHTML Cookbook"      Published by O'Reilly & Associates      Copyright 2003 Danny Goodman --> <html> <head> <title>Recipe 10.8</title> <style id="main" type="text/css"> body {background-color:#eeeeee; font-family:Arial,Helvetica,sans-serif; font-size:12px;} h1 {font-size:2.0em; font-weight:bold} </style> <style rel="stylesheet" type="text/css"> .menuWrapper {               position:absolute;                width:162px;                background-color:#339966;                visibility:hidden;                border-style:solid;                border-width:2px;                border-color:#EFEFEF #505050 #505050 #EFEFEF;               display:block;               padding:3px;               } .menuItem    {               cursor:pointer;                font-size:12px;                font-family:Arial, Helvetica, sans-serif;                border-bottom:1px solid #505050;                border-top:1px solid #EFEFEF;               padding-left:10px;                color:black;                background-color:#339966;                text-decoration:none;                position:absolute;                left:0px;                width:159px;                height:1.4em;               display:block;               line-height:1.4em              } .menuItemOn  {               cursor:pointer;                font-size:12px;                font-family:Arial, Helvetica, sans-serif;                border-bottom:1px solid #505050;                border-top:1px solid #EFEFEF;               padding-left:10px;                color:#000000;                background-color:#33ff00;                text-decoration:underline;                position:absolute;                left:0px;                width:159px;                height:1.4em;               display:block;               line-height:1.4em              } </style> <script language="JavaScript" type="text/javascript"> // global menu state var menuReady = false; // pre-cache menubar image pairs if (document.images) {     var imagesNormal = new Array();     imagesNormal["home"] = new Image(20, 80);     imagesNormal["home"].src = "home_off.jpg";     imagesNormal["catalog"] = new Image(20, 80);     imagesNormal["catalog"].src  = "catalog_off.jpg";     imagesNormal["about"] = new Image(20, 80);     imagesNormal["about"].src  = "about_off.jpg";     var imagesHilite = new Array();     imagesHilite["home"] = new Image(20, 80);     imagesHilite["home"].src = "home_on.jpg";     imagesHilite["catalog"] = new Image(20, 80);     imagesHilite["catalog"].src  = "catalog_on.jpg";     imagesHilite["about"] = new Image(20, 80);     imagesHilite["about"].src  = "about_on.jpg"; } function getElementStyle(elem, IEStyleProp, CSSStyleProp) {     if (elem.currentStyle) {         return elem.currentStyle[IEStyleProp];     } else if (window.getComputedStyle) {         var compStyle = window.getComputedStyle(elem, "");         return compStyle.getPropertyValue(CSSStyleProp);     }     return ""; } // carry over some critical menu style sheet attribute values var CSSRuleValues = {menuItemHeight:"18px",                      menuItemLineHeight:"1.4em",                      menuWrapperBorderWidth:"2px",                      menuWrapperPadding:"3px",                      defaultBodyFontSize:"12px"                     }; // specifications for menu contents and menubar image associations var menus = new Array(); menus[0] = {mBarImgId:"menuImg_1",             mBarImgNormal:imagesNormal["home"],             mBarImgHilite:imagesHilite["home"],             menuItems:[],             elemId:""            }; menus[1] = {mBarImgId:"menuImg_2",             mBarImgNormal:imagesNormal["catalog"],             mBarImgHilite:imagesHilite["catalog"],             menuItems:[ {text:"Deluxe Line", href:"catalog_deluxe.html"},                         {text:"Budget Line", href:"catalog_budget.html"},                         {text:"Export", href:"catalog_export.html"},                         {text:"Order Print Catalog", href:"catalog_order.html"}                       ],             elemId:""            }; menus[2] = {mBarImgId:"menuImg_3",              mBarImgNormal:imagesNormal["about"],             mBarImgHilite:imagesHilite["about"],             menuItems:[ {text:"Press Releases", href:"press.html"},                         {text:"Executive Staff", href:"staff.html"},                         {text:"Map to Our Offices", href:"map.html"},                         {text:"Company History", href:"history.html"},                         {text:"Job Postings", href:"jobs.html"},                         {text:"Contact Us", href:"contact.html"}                       ],             elemId:""            }; // create hash table-like lookup for menu objects with id string indexes function makeHashes() {     for (var i = 0; i < menus.length; i++) {         menus[menus[i].elemId] = menus[i];         menus[menus[i].mBarImgId] = menus[i];     } } // assign menu label image event handlers function assignLabelEvents() {     var elem;     for (var i = 0; i < menus.length; i++) {         elem = document.getElementById(menus[i].mBarImgId);         elem.onmouseover = swap;         elem.onmouseout = swap;     } } // invoked from init(), generates the menu div elements and their contents. // all this action is invisible to user during construction function makeMenus() {     var menuDiv, menuItem, itemLink, mbarImg, textNode, offsetLeft, offsetTop;          // determine key adjustment factors for the total height of menu divs          var menuItemH = 0;     var bodyFontSize = parseInt(getElementStyle(document.body, "fontSize", "font-size"));     // test to see if browser's font size has been adjusted by the user     // and that the new size registers as an applied style property     if (bodyFontSize == parseInt(CSSRuleValues.defaultBodyFontSize)) {         menuItemH = (parseFloat(CSSRuleValues.menuItemHeight));     } else {         // works nicely in Netscape 7         menuItemH = parseInt(parseFloat(CSSRuleValues.menuItemLineHeight) * bodyFontSize);     }     var heightAdjust = parseInt(CSSRuleValues.menuWrapperPadding) +          parseInt(CSSRuleValues.menuWrapperBorderWidth);     if (navigator.appName == "Microsoft Internet Explorer" &&          navigator.userAgent.indexOf("Win") != -1 &&          (typeof document.compatMode == "undefined" ||          document.compatMode == "BackCompat")) {         heightAdjust = -heightAdjust;     }          // use menus array to drive div creation loop     for (var i = 0; i < menus.length; i++) {         menuDiv = document.createElement("div");         menuDiv.id = "popupmenu" + i;         // preserve menu's ID as property of the menus array item         menus[i].elemId = "popupmenu" + i;         menuDiv.className = "menuWrapper";         if (menus[i].menuItems.length > 0) {             menuDiv.style.height = (menuItemH * menus[i].menuItems.length) -              heightAdjust + "px";         } else {             // don't display any menu div lacking menu items             menuDiv.style.display = "none";         }         // define event handlers         menuDiv.onmouseover = keepMenu;         menuDiv.onmouseout = requestHide;         // set stacking order in case other layers are around the page         menuDiv.style.zIndex = 1000;                  // assemble menu item elements for inside menu div         for (var j = 0; j < menus[i].menuItems.length; j++) {             menuItem = document.createElement("div");             menuItem.id = "popupmenuItem_" + i + "_" + j;             menuItem.className = "menuItem";             menuItem.onmouseover = toggleHighlight;             menuItem.onmouseout = toggleHighlight;             menuItem.onclick = hideMenus;             menuItem.style.top = menuItemH * j + "px";             itemLink = document.createElement("a");             itemLink.href = menus[i].menuItems[j].href;             itemLink.className = "menuItem";             itemLink.onmouseover = toggleHighlight;             itemLink.onmouseout = toggleHighlight;             textNode = document.createTextNode(menus[i].menuItems[j].text);             itemLink.appendChild(textNode);             menuItem.appendChild(itemLink);             menuDiv.appendChild(menuItem);         }         // append each menu div to the body         document.body.appendChild(menuDiv);     }     makeHashes();     assignLabelEvents();     // pre-position menu     for (i = 0; i < menus.length; i++) {         positionMenu(menus[i].elemId);     }     menuReady = true; } // initialize global that helps manage menu hiding var timer; // invoked from mouseovers inside menus to cancel hide // request from mouseout of menu bar image et al. function keepMenu() {     clearTimeout(timer); } function cancelAll() {     keepMenu();     menuReady = false; } // invoked from mouseouts to request hiding all menus // in 1/4 second, unless cancelled function requestHide() {     timer = setTimeout("hideMenus()", 250); } // "brute force" hiding of all menus and restoration // of normal menu bar images function hideMenus() {     for (var i = 0; i < menus.length; i++) {        document.getElementById(menus[i].mBarImgId).src = menus[i].mBarImgNormal.src;        var menu = document.getElementById(menus[i].elemId)        menu.style.visibility = "hidden";     } } // set menu position just before displaying it function positionMenu(menuId){     // use the menu bar image for position reference of related div     var mBarImg = document.getElementById(menus[menuId].mBarImgId);     var offsetTrail = mBarImg;     var offsetLeft = 0;     var offsetTop = 0;     while (offsetTrail) {         offsetLeft += offsetTrail.offsetLeft;         offsetTop += offsetTrail.offsetTop;         offsetTrail = offsetTrail.offsetParent;     }     if (navigator.userAgent.indexOf("Mac") != -1 &&          typeof document.body.leftMargin != "undefined") {         offsetLeft += document.body.leftMargin;         offsetTop += document.body.topMargin;     }     var menuDiv = document.getElementById(menuId);     menuDiv.style.left = offsetLeft + "px";     menuDiv.style.top = offsetTop + mBarImg.height + "px"; } // display a particular menu div function showMenu(menuId) {     if (menuReady) {         keepMenu();         hideMenus();         positionMenu(menuId);         var menu = document.getElementById(menuId);         menu.style.visibility = "visible";     } } // menu bar image swapping, invoked from mouse events in menu bar // swap style sheets for menu items during rollovers function toggleHighlight(evt) {     evt = (evt) ? evt : ((event) ? event : null);     if (typeof menuReady != "undefined") {         if (menuReady && evt) {             var elem = (evt.target) ? evt.target : evt.srcElement;             if (elem.nodeType == 3) {                 elem = elem.parentNode;             }             if (evt.type == "mouseover") {                 keepMenu();                 elem.className ="menuItemOn";             } else {                 elem.className ="menuItem";                 requestHide();             }             evt.cancelBubble = true;         }     } } function swap(evt) {     evt = (evt) ? evt : ((event) ? event : null);     if (typeof menuReady != "undefined") {         if (evt && (document.getElementById && document.styleSheets) && menuReady) {             var elem = (evt.target) ? evt.target : evt.srcElement;             if (elem.className == "menuImg") {                 if (evt.type == "mouseover") {                     showMenu(menus[elem.id].elemId);                     elem.src = menus[elem.id].mBarImgHilite.src;                 } else if (evt.type == "mouseout") {                     requestHide();                 }                 evt.cancelBubble = true;             }         }     } } // create menus only if key items are supported function initMenus() {     if (document.getElementById && document.styleSheets) {         setTimeout("makeMenus()", 5);         window.onunload=cancelAll;     } } </script> </head> <body onload="initMenus()"> <h1>Drop-Down Menus</h1> <hr /> <div id="menubar"> <a href="index.html"><img id="menuImg_1" class="menuImg"  src="home_off.jpg" border="0" height="20"  width="80"></a><a href="catalog.html"><img id="menuImg_2"  class="menuImg" src="catalog_off.jpg" border="0" height="20"  width="80"></a><a href="about.html"><img id="menuImg_3"  class="menuImg" src="about_off.jpg" border="0" height="20" width="80"></a> </div> </body> </html>