用于 Web 的另一个 XP 风格面板栏






4.67/5 (53投票s)
Web 应用程序的 XP 风格面板栏。
引言
Windows XP 用户已经熟悉了出现在 Windows 资源管理器左侧的面板栏。 本文介绍了在 Web 应用程序中模仿此用户界面的另一种方法。 本文的灵感来自于 CodeProject 上另一篇很棒的文章 Windows XP 风格菜单。 但是,本文中提出的想法大量使用表格来格式化面板栏内容,并且还提供了一种在运行时更改样式表的方法。
面板栏布局
下图显示了面板栏中单个项目的 HTML 布局。 面板栏中的每个其他项目都遵循完全相同的布局。
- 整个面板栏被包裹在一个
div
标签中。 - 实际的面板栏由两个
div
标签形成。 主要是Header
和Links
。 - 标题被渲染为一个单行
table
。 - 项目链接再次被渲染为
table
行。
整个面板栏 HTML 在运行时使用客户端 JavaScript 生成。 因此,您无需包含任何 HTML,就像大多数其他我见过的面板栏一样。
驱动脚本
面板栏需要两个 JavaScript 文件。 Panelbar.js 文件包含菜单生成的实际代码,而 ua.js 包含用于浏览器检测的脚本。 您希望显示面板栏的页面需要发出以下 JavaScript 代码
<script language="javascript">
var objTmp;
objTmp = createMenu("Community", "");
createSubMenu(objTmp, "Site Map", "PanelBar.htm#", "", "", "", "WKSpace");
createSubMenu(objTmp, "Add To Favorites",
"PanelBar.htm#", "", "", "", "WKSpace");
createSubMenu(objTmp, "CodeProject Stuff",
"PanelBar.htm#", "", "", "", "WKSpace");
createSubMenu(objTmp, "Who's Who", "PanelBar.htm#", "", "", "", "WKSpace");
createSubMenu(objTmp, "Tell a friend", "PanelBar.htm#",
"", "", "", "WKSpace");
createSubMenu(objTmp, "Industry Contacts",
"PanelBar.htm#", "", "", "", "WKSpace");
objTmp = createMenu(".NET", "");
createSubMenu(objTmp, "ASP.NET", "PanelBar.htm#", "", "", "", "WKSpace");
createSubMenu(objTmp, "Managed C++", "PanelBar.htm#", "", "", "", "WKSpace");
createSubMenu(objTmp, "SOAP & XML", "PanelBar.htm#", "", "", "", "WKSpace");
createSubMenu(objTmp, "VB.NET", "PanelBar.htm#", "", "", "", "WKSpace");
createSubMenu(objTmp, "C++ Web Services",
"PanelBar.htm#", "", "", "", "WKSpace");
createSubMenu(objTmp, "Compact Framework",
"PanelBar.htm#", "", "", "", "WKSpace");
createSubMenu(objTmp, "Cross Platform", "PanelBar.htm#", "", "", "", "WKSpace");
setTheme("XPClassic.css", null, null)
initialize(150);
</script>
createMenu
函数接受两个参数。 第一个是标题文本,第二个是工具提示文本。 目前,此参数被忽略。 将来,这可以与 span
标签的 title
属性一起使用,并将标题文本包含在其中。
createSubMenu
函数接受以下六个参数
- 指向要渲染链接项目的标题对象的引用。
- 要显示的链接文本。
- 链接 URL。
- 通过查询字符串传递给链接 URL 的额外数据。
- 要为链接显示的工具提示文本。
- 要在链接文本之前渲染的图像文件的名称。
- 最后,链接应该打开的目标
window
或frame
名称。
setTheme
基本上允许菜单自定义。 它接受以下三个参数
- 自定义 CSS 文件的名称。
- 包含自定义主题文件的文件夹的相对路径和名称。 默认值为
CSS
。 - 包含自定义主题中使用的图像的文件夹的相对路径和名称。 默认值为
IMAGES
。
最后,initialize
函数接受一个参数,并使用它来决定面板栏的宽度。 此函数还负责生成必要的 HTML。
JavaScript 结构
面板栏由以下 JavaScript 结构组成。 MenuBand
结构包含渲染标题部分所需的信息。 它还包含一个子项数组。 drawMenu
成员负责渲染标题和子项。
/********************
* Header structure *
*******************/
function MenuBand(pstrDesc, pstrTip)
{
// Properties
this.id = ""; //generated at runtime.
this.label = pstrDesc; //Text to be displayed in header
this.microHelp = pstrTip; //Tooltip text
this.isHeader = true;
this.open = false; //future use
this.submenu = new Array; //array containing link items.
this.smcount = 0; //count of sub items.
//Methods
this.addSubMenu = addSubMenu; //function for item addition
this.render = drawMenu; //function for rendering header
}
SubMenu
结构包含渲染单个子项所需的信息。 同样,它也有一个 drawMenu
成员,负责渲染此子项。 此成员从 MenuBand
的 drawMenu
成员调用。
/**********************
* Sub item structure *
*********************/
function SubMenu(pstrDesc, pstrLink, pstrLinkData, pstrTip, pstrImage, pstrTarget)
{
// Properties
this.parentId = ""; //populated at runtime
this.label = pstrDesc; //Item text to be displayed
this.hlink = pstrLink; //Link url
this.linkTarget = pstrTarget; //Target window and or frame identifier
this.linkData = pstrLinkData; //Exrta data to be passed through querystring.
this.microHelp = pstrTip; //Tooltip text.
this.isHeader = false;
this.isSelected = false; //future use
this.iconSrc = pstrImage; //Name of the image file.
//Methods
this.render = drawSubMenu; //function for rendering sub item.
}
绘图函数
面板栏构造中两个最重要的函数是 drawMenu
和 drawSubMenu
。 顾名思义,drawMenu
渲染标题部分并为每个子项调用 drawSubMenu
以渲染单个子项。
/*************************************************************
* Render header part and for each sub item invokes drawMenu.*
************************************************************/
function drawMenu()
{
var iCntr = 0;
var objMenu;
var strId, strLbl;
document.write("<div class=\"menuHeaderCollapsed\" id=\"" + this.id + "\"" +
" onmouseover=\"mousehover(this)\"" +
" onmouseout=\"mouseout(this)\"" +
"onclick=\"toggle(this)\">");
document.write("<table border=\"0\" cellspacing=\"0\"" +
" cellpadding=\"4\" width=\"100%\">");
document.write("<tr><td style=\"vertical-align: center;\">" +
this.label + "</td></tr>");
document.write("</table></div>");
//start drawing sub menu
document.write("<div style=\"display: none; visibility: hidden;\"" +
" class=\"menuItems\" id=\"" + this.id + "_child" + "\">");
document.write("<table border=\"0\" cellspacing=\"0\"" +
" cellpadding=\"4\" width=\"100%\">");
for (iCntr = 0; iCntr < this.smcount; iCntr++)
{
this.submenu[iCntr].render();
}
document.write("</table></div>");
}
/********************
* Renders sub item.
*******************/
function drawSubMenu()
{
var strImg = "";
document.write("<tr><td>");
if (this.iconSrc)
strImg = "<img src=\"" + _strCtxt + _imageFolder + "/" +
this.iconSrc + " border=\"0\"\"> ";
document.write("<a href=" +
getLink(this.linkTarget, (_strCtxt + this.hlink), this.linkData) +
"\">");
document.write(strImg);
document.write(this.label);
document.write("</a>");
document.write("</td></tr>");
}
样式表
使用的样式表(s) 实际上没有什么特别之处。 附带的源文件包含四个不同的样式表。 以下样式表渲染 Code Project 面板栏
body
{
font-family: Verdana, Tahoma, Arial;
font-size: 8pt;
font-weight: normal;
background-color: #FC9A04;
}
#panelBar
{
background-color: #FC9A04;
height: 100%;
width: 100%;
vertical-align: top;
}
.menuHeaderExpanded
{
font-family: Verdana, Tahoma, Arial;
font-size: 8pt;
font-weight: bold;
background-image: url('../Images/CPExpand.gif');
background-position: right center;
background-repeat: no-repeat;
color: #FC9A04;
height: 23px;
cursor: hand;
border-left: 1px solid #000000;
}
.menuHeaderExpandedOver
{
font-family: Verdana, Tahoma, Arial;
font-size: 8pt;
font-weight: bold;
background-image: url('../Images/CPExpand.gif');
background-position: right center;
background-repeat: no-repeat;
color: #FC9A04;
height: 23px;
cursor: hand;
border-left: 1px solid #000000;
}
.menuHeaderExpanded td
{
color: #FC9A04;
font-size: 8pt;
font-weight: normal;
}
.menuHeaderExpandedOver td
{
color: #FC9A04;
font-size: 8pt;
font-weight: bold;
}
.menuHeaderCollapsed
{
font-family: Verdana, Tahoma, Arial;
font-size: 8pt;
font-weight: bold;
background-image: url('../Images/CPCollapse.gif');
background-position: right center;
background-repeat: no-repeat;
color: #FC9A04;
height: 23px;
cursor: hand;
border-left: 1px solid #000000;
}
.menuHeaderCollapsedOver
{
font-family: Verdana, Tahoma, Arial;
font-size: 8pt;
font-weight: bold;
background-image: url('../Images/CPCollapse.gif');
background-position: right center;
background-repeat: no-repeat;
color: #FC9A04;
height: 23px;
cursor: hand;
border-left: 1px solid #000000;
}
.menuHeaderCollapsed td
{
color: #FC9A04;
font-size: 8pt;
font-weight: normal;
}
.menuHeaderCollapsedOver td
{
color: #FC9A04;
font-size: 8pt;
font-weight: bold;;
}
.menuItems
{
font-family: Verdana, Tahoma, Arial;
font-size: 8pt;
background-color: #FFCC99;
color: #000000;
position: relative;
}
.menuItems table
{
font-family: Tahoma, Verdana, Arial;
font-size: 8pt;
background-color: #FFCC99;
color: #000000;
border-top: 1px solid #000000;
border-left: 1px solid #000000;
border-right: 1px solid #000000;
border-bottom: 1px solid #000000;
}
.menuItems a
{
color: #000000;
text-decoration: none;
}
.menuItems a:hover
{
color: #000000;
font-weight: bold;
text-decoration: none;
}
Possible Enhancements
- 支持 Internet Explorer 6.0 和 FireFox 1.0 以外的浏览器。
- 支持标题工具提示。
- 鼠标悬停时在子项目周围绘制边框。
修订历史
- 2005 年 2 月 11 日
首次发布。
- 2005 年 2 月 17 日
修复了图像和样式表,以删除箭头方向错误。
- 2005 年 4 月 13 日
修复了子项未显示的图像错误。
- 2005年8月17日
- 支持单个面板的背景图像。
- 支持多个面板实例。