65.9K
CodeProject 正在变化。 阅读更多。
Home

网页上的 Windows 式菜单

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.12/5 (22投票s)

2000年8月15日

viewsIcon

178773

downloadIcon

4909

如何使用 Javascript 和 HTML 创建菜单。

请稍等 ...

在我们继续之前,请下载上面的代码,查看本文讨论的示例。请注意,文章文本指的是原始的仅适用于 IE 的代码。更新后的源代码适用于 Netscape 6+ 和 IE。

关于菜单

使用 JavaScript 或 VBScript,我们可以生成一些非常酷的用户界面 (UI) 项目,例如菜单。DIV 元素在创建菜单时非常有用,因为它可以模拟下拉和/或弹出菜单的效果。但是,Netscape Navigator 存在兼容性问题,DIV 元素无法产生与 Internet Explorer 相同的效果。 解决方案是在为 Netscape 浏览器开发时使用 Netscape 等效元素 LAYERILAYER 等。本文仅讨论如何为 Internet Explorer 创建菜单的想法,对于 Netscape Navigator,逻辑保持不变,只有细微的变化。

创建一个菜单

每个菜单由菜单项组成。每个菜单都是一个 DIV 元素,可以包含其他 DIV 元素(菜单项)。 在示例中,您看到的每个菜单项以及分隔条都是应用了样式的 DIV 元素。菜单/菜单项对用户的显示方式取决于为每个 DIV 元素设置的样式属性。 可用于菜单的可能样式属性包括背景颜色、边框、文本颜色等。DIV 元素还支持 mouseovermouseout 等事件,这使菜单/菜单项能够对用户做出反应。 包含的 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); }
现在您一定对 CreateMenuBarCreateSeparatorBar 中的内容有所了解。 这里有一件重要的事情需要注意,在 CreateSeparatorBar 中使用 IMG 标签可确保分隔符的大小等于边框(我不知道还有没有其他方法可以做到这一点...)。 OnMouseOverBarOnMouseOutOfBaronmenuclick 是鼠标事件的简单处理程序。
 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。 此外,还添加了一个新函数来支持将原始弹出菜单附加到表格单元格。

© . All rights reserved.