Drop-Down Menus : Menu : GUI Components : JavaScript DHTML examples (example source code) Organized by topic

JavaScript DHTML
C++
PHP
JavaScript DHTML Home »  GUI Components   » [  Menu  ]   
 



Drop-Down Menus

Please note that some example is only working under IE or Firefox.

 <!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(2080);
    imagesNormal["home"].src = "home_off.jpg";
    imagesNormal["catalog"new Image(2080);
    imagesNormal["catalog"].src  = "catalog_off.jpg";
    imagesNormal["about"new Image(2080);
    imagesNormal["about"].src  = "about_off.jpg";

    var imagesHilite = new Array();
    imagesHilite["home"new Image(2080);
    imagesHilite["home"].src = "home_on.jpg";
    imagesHilite["catalog"new Image(2080);
    imagesHilite["catalog"].src  = "catalog_on.jpg";
    imagesHilite["about"new Image(2080);
    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"!= -&& 
        (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"!= -&& 
        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>


           
       
Related examples in the same category
1.  Application Menubar ExampleHas Download File
2.  [DOM Menu] :: Example 1 :: Horizontal MenuHas Download File
3.  [DOM Menu] :: Example 2 :: KDE Keramik Style MenuHas Download File
4.  [DOM Menu] :: Example 3: Brainjar.com 'Revenge of the Menubar' Style MenuHas Download File
5.  [DOM Menu] Example 4: Vertical MenuHas Download File
6.  [DOM Menu] :: Example 5 :: Two MenusHas Download File
7.  [DOM Menu] :: Example 6 :: Flash HidingHas Download File
8.  Menu bar for an inner fake window
9.  Fly in Menu item
10.  Not too fancy menu with toolbarHas Download File
11.  Custom Contextual Menu(content sensitive)
12.  Menu with soundHas Download File
13.  Menu based on JavascriptHas Download File
14.  popup menu (content sensitive menu)
15.  Complete Source Code for the Menu
16.  Slide out menu
17.  Dynamic menu: fly in
18.  Menu and submenu
19.  Slide out menu with i18NHas Download File
20.  Menu: XP, win 98 styleHas Download File
21.  Simple drop-down menu example with layer
22.  Build a simple fancy menuHas Download File
23.  Add/delete menu itemsHas Download File
24.  Customizable layout: customize menu layoutHas Download File
25.  Vertical layout menuHas Download File
26.  Easy skinable menu with CSSHas Download File
27.  Menu Item propertiesHas Download File
28.  Direct link menuHas Download File
29.  Context menu: popup menuHas Download File
30.  Black Menu
31.  Dropdown menuHas Download File
























Home| Contact Us
Copyright 2003 - 04 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.