Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Windows like menus on web pages

0.00/5 (No votes)
10 Jan 2003 2  
How to create menus using Javascript and HTML.

Wait ...

Before we move any further, examine the sample, which this article discusses, by grabbing the code above. Note that the article text refers to the original IE-only code. The updated source code works for Netscape 6+ as well as IE.

About Menus

Using JavaScript or VBScript we can produce some very cool user interface (UI) items like menus. The DIV element is useful when creating menus in that it can simulate the effect of pull-down and/or pop-up menus. However there is a compatibility problem with Netscape Navigator, DIV elements do not produce the same effects as Internet Explorer. The solution is to use the Netscape equivalent elements of LAYER ,ILAYER and the like when developing for the Netscape browser. This article only discusses the idea of how to create menus for Internet Explorer, for Netscape Navigator however the logic remains the same with only minor changes.

Create A Menu

Each menu consists of menu items. Each menu is a DIV element that can contain other DIV elements (the menu items). In the example each menu item that you see as well as the separator bar is a DIV element with a style applied. How the menu/menu item appears to the user depends on what style attributes are set for each DIV element. Possible style attributes that could be used for menus are background color, borders, text color, etc. DIV elements also support events like mouseover and mouseout, this enables the menu/menu items to react to the user. Contained DIV elements inherit the style of their parents, i.e. if the parent is invisible so are the children. Now does all that ring any bells? In the following sections we will see this put to work, starting with the CreateMenu function.

In The Code

  • hColor = highlight color, the color of a menu item when it is in a highlighted state.
  • dColor = default color, the normal color of a menu item.
  • bColor = background color, color of the parent DIV element that contains menu items, this is also the color of separators.
  • menuArr = global two dimensional array that contains the data for the menus.
  • titles = global two dimensional array that contains the text to display for each top level menu and the number of menu items under each menu.
 function show(obj)
 {
     obj.style.visibility = 'visible';
 }

 function hide(obj)
 {
    obj.style.visibility = 'hidden';
 }

 function CreateMenu(rowid,x,y,width,height,hColor,dColor,bColor,items,align,
border) { if(!items) { return; // if no items specified just return } var divHTML ; var menuBar; // Create HTML for top level menu, this one is always visible. //--> menuBar ="<DIV id=\"main_div_" + rowid + "\" align=\""+align+"\" "; menuBar += " style=\" position:absolute; CURSOR:hand; top:" + y + "px; left:" + x + "px; width:" + width + "px; "; menuBar += " height:" + height + "px; visibility:visible; " +
"background-color:" + dColor + ";\" "; menuBar += " onmouseover=\"show(document.all[\'div_"+ rowid + "\']);\" onmouseout=\"hide(document.all[\'div_"+ rowid +
"\']);\">"; menuBar += titles[rowid][0] + " </DIV>"; document.write (menuBar); y += document.all["main_div_" + rowid ].offsetHeight; // Create HTML for menu item container with hidden style. divHTML = "<DIV id=\"div_"+rowid+"\"" ; divHTML += "style=\"position:absolute; top:" + y + "px; left:" + x +
"px; width:" + width + "px; visibility:hidden; "; divHTML += " padding-left:" + border + "; background-color:" + bColor +
";\" "; divHTML += "onmouseover=\"show(this);\" onmouseout=\"hide(this);\" >\n"; divHTML += CreateSeparatorBar(bColor,width-(border*2),border); // Create HTML for menu items and separators, visibility of each menu
// item is inherited as the visibility of its container.
for (i=0;i<items;i++) { divHTML += CreateMenuBar('div_'+rowid,rowid,i,width-(border*2), height,hColor,dColor,align); divHTML += CreateSeparatorBar(bColor,width-(border*2),border); } divHTML += "</DIV>"; document.write(divHTML); }
By now you must have an idea of what to expect in CreateMenuBar and CreateSeparatorBar. There is one important thing to note here, the use of an IMG tag in the CreateSeparatorBar ensures that the size of the separator is equal to the border (There is no other way to do it that I know...). OnMouseOverBar , OnMouseOutOfBar and onmenuclick are simple handlers for mouse events.
 function OnMouseOverBar(obj,rowid,colid,color)
 {
    obj.style.backgroundColor = color;
    window.status = menuArr[rowid][colid][2];
 }

 function OnMouseOutOfBar(obj,rowid,colid,color)
 {
    obj.style.backgroundColor = color;
    window.status = "";
 }

function onmenuclick(obj,code)
{
    hide(obj);
    eval(code); // execute the code corresponding to a menu item. 

}


 function CreateSeparatorBar(dColor,width,border)
 {
    var sepHTML; 
    sepHTML = "<DIV id=\"line_separator\" style=\"position:relative; " +
"height:1px;" + " background-color:"+dColor+";\" >"; sepHTML += "<img src=\"\" width=" + width + " height="+
border/2+"></DIV> \n"; return sepHTML; } function CreateMenuBar(parent,rowid,colid,width,height,hColor,dColor,align) { var subMenuHTML; subMenuHTML = "\n<DIV align="+align+" id=\"div_"+rowid + "_"+colid+"\" style=\"position:relative; CURSOR:hand; "; subMenuHTML += " width:"+width+"px; background-color:"+dColor+";\" "; subMenuHTML += " onmouseover=\"OnMouseOverBar(this,"+rowid+","+
colid+",\'"+ hColor+"\');\" "; subMenuHTML += " onclick=\"onmenuclick(document.all[\'"+parent+"\'],\'" + menuArr[rowid][colid][1] + "\');\" "; subMenuHTML += " onmouseout=\"OnMouseOutOfBar(this,"+rowid+","+colid+ ",\'"+dColor+"\');\" >"; subMenuHTML += menuArr[rowid][colid][0]; subMenuHTML += " </DIV> \n"; return subMenuHTML; }

Displaying the menu.

All that is left to display the menu is to provide data for the menu. This is done using a two dimensional array. For simplicity these variables have been kept global.
 var  menuArr;
 var  titles;

 function Initialize(rows,cols)
 {
  menuArr = new Array();
  titles =  new Array();
  for(i=0; i< rows; i++)
  {
     titles[i] =  new Array(2)
     titles[i][0] = "";     // Title to display in top level menu.

     titles[i][1] = 0;      //number of items in drop down menu.

  }
  for (i= 0;i <  rows; i++) 
  {
    menuArr[i] = new Array(cols)
    for (j= 0;j <  cols; j++) 
    {
        menuArr[i][j] = new Array(3)
        for (k=0; k < 3 ; k++)
         menuArr [i][j][k] = ""; // k=0 is for menu text.

                                 // k=1 is for the link to navigate to

                                 //     when menu is selected 

                                 // k=2 is the text that is displayed in 

                                        status window.
    }
  }
 }
 
 Initialize(1,4);            // One menu with three menu items.

 titles[0][0] = "File"; 
 titles[0][1] = 4;

 menuArr[0][0][0]="New";
 menuArr[0][0][1]="window.navigate(\\\'cool.html\\\');"
 menuArr[0][0][2]="open a new file.";

 menuArr[0][1][0]="Save";
 menuArr[0][1][1]="alert(\\\'save this document\\\');";
 menuArr[0][1][2]="save this document.";

 menuArr[0][2][0]="Exit"
 menuArr[0][2][1]="window.close();";
 menuArr[0][2][2]="see you later.";

 menuArr[0][3][0]="mail me...";
 menuArr[0][3][1]="window.navigate(\\\'mailto:alleey@usa.net\\\');";
 menuArr[0][3][2]="alleey@usa.net";
    
 for(i=0;i < 4; i++)
 {
    CreateMenu(i,i*150,0,150,15,'#000099','#999999','#c0c0c0',
               titles[i][1],'center',4);
 }    

If there are no errors, this should produce a menu on the page. The code can also be used to create pop-up menus. To add this functionality, a way to position the menu inside the browser window where the mouse click has occurred is need. The window object has an event object that holds information about the last event occurred. For a mouse event, window.event holds the x and y coordinates where the event occurred along with the button state and other useful information.

 function TrackPopUp(obj)
 {
    if(typeof(obj) == "undefined") // just a simple check to avoid runtime 

        return;                    // errors.

    var winWidth  = document.body.clientWidth;
    var winHeight = document.body.clientHeight;
    x = winWidth - (obj.offsetWidth + window.event.x); // see if the menu is 

                                                       // not entirely visible 

                                                       // inside the window we 

                                                       // shift the origin in
// the case when the
// menu is not. y = winHeight - (obj.offsetHeight + window.event.y); obj.style.left = x<0 ? window.event.x + x : window.event.x ; obj.style.top = y<0 ? window.event.y + y : window.event.y; show(obj); return false; } <SCRIPT LANGUAGE="javascript" FOR=document EVENT=oncontextmenu> <!-- return TrackPopUp(document.all['div_0']); // here 'div_0' is the name of the
// DIV
//--> </SCRIPT>
If we do not return false from TrackPopUp the default IE menu will appear at the same time as our popup menu.

Final words.

This is fairly cool way to provide navigation in HTML pages. Here I am displaying just one menu. Depending on your situation, you can write code to change the menu that is displayed. By doing some extra work, self-modifying menus can be incorporated. There are so many cool things you can do with this, it is all up to you.

History

The original article by Shoaib Ali's was for MS IE only. This update by JavasOK tweaks the original slightly to extend its use to Netscape/Mozilla. In addition a new function has been added to support attaching the original popup menu to a table cell.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here