网页上的 Windows 式菜单






4.12/5 (22投票s)
2000年8月15日

178773

4909
如何使用 Javascript 和 HTML 创建菜单。
请稍等 ...
在我们继续之前,请下载上面的代码,查看本文讨论的示例。请注意,文章文本指的是原始的仅适用于 IE 的代码。更新后的源代码适用于 Netscape 6+ 和 IE。关于菜单
使用 JavaScript 或 VBScript,我们可以生成一些非常酷的用户界面 (UI) 项目,例如菜单。DIV
元素在创建菜单时非常有用,因为它可以模拟下拉和/或弹出菜单的效果。但是,Netscape Navigator 存在兼容性问题,DIV
元素无法产生与 Internet Explorer 相同的效果。 解决方案是在为 Netscape 浏览器开发时使用 Netscape 等效元素 LAYER
、ILAYER
等。本文仅讨论如何为 Internet Explorer 创建菜单的想法,对于 Netscape Navigator,逻辑保持不变,只有细微的变化。创建一个菜单
每个菜单由菜单项组成。每个菜单都是一个DIV
元素,可以包含其他 DIV
元素(菜单项)。 在示例中,您看到的每个菜单项以及分隔条都是应用了样式的 DIV
元素。菜单/菜单项对用户的显示方式取决于为每个 DIV
元素设置的样式属性。 可用于菜单的可能样式属性包括背景颜色、边框、文本颜色等。DIV
元素还支持 mouseover
和 mouseout
等事件,这使菜单/菜单项能够对用户做出反应。 包含的 DIV
元素继承其父元素的样式,即,如果父元素不可见,则子元素也不可见。 现在所有这些是否引起了你的注意? 在以下各节中,我们将看到它开始工作,从 CreateMenu
函数开始。在代码中
hColor
= 高亮颜色,菜单项处于高亮状态时的颜色。dColor
= 默认颜色,菜单项的正常颜色。bColor
= 背景颜色,包含菜单项的父DIV
元素的颜色,这也是分隔符的颜色。menuArr
= 全局二维数组,包含菜单的数据。titles
= 全局二维数组,包含要为每个顶级菜单显示的文本以及每个菜单下的菜单项数。
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);
}
现在您一定对 CreateMenuBar
和 CreateSeparatorBar
中的内容有所了解。 这里有一件重要的事情需要注意,在 CreateSeparatorBar
中使用 IMG
标签可确保分隔符的大小等于边框(我不知道还有没有其他方法可以做到这一点...)。 OnMouseOverBar
、OnMouseOutOfBar
和 onmenuclick
是鼠标事件的简单处理程序。 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;
}
显示菜单。
要显示菜单,剩下的就是为菜单提供数据。 这是使用二维数组完成的。 为了简单起见,这些变量保持全局变量。 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);
}
如果没有错误,这应该会在页面上生成一个菜单。 该代码还可用于创建弹出菜单。 要添加此功能,需要一种将菜单定位在浏览器窗口内鼠标单击发生的位置的方法。 window
对象有一个 event
对象,其中包含有关上次发生的事件的信息。 对于鼠标事件,window.event
包含事件发生的 x 和 y 坐标,以及按钮状态和其他有用信息。
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>
如果我们不从 TrackPopUp
返回 false,默认的 IE 菜单将与我们的弹出菜单同时出现。最后的话。
这是一种在 HTML 页面中提供导航的非常酷的方式。 在这里我只显示一个菜单。 根据您的情况,您可以编写代码来更改显示的菜单。 通过做一些额外的工作,可以合并自修改菜单。 你可以用它做很多很酷的事情,这完全取决于你。历史
Shoaib Ali 的原始文章仅适用于 MS IE。 JavasOK 的此更新略微调整了原始版本,以将其用途扩展到 Netscape/Mozilla。 此外,还添加了一个新函数来支持将原始弹出菜单附加到表格单元格。