Windows like menus on web pages






4.12/5 (22 votes)
Aug 15, 2000

178131

4909
How to create menus using Javascript and HTML.
- Download source files - 3.82 Kb (original version - IE only)
- Download source files - 5.35 Kb (updated version - IE/Netscape)
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. TheDIV
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 aDIV
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 parentDIV
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.