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

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

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.67/5 (53投票s)

2005年2月11日

CPOL

3分钟阅读

viewsIcon

169934

downloadIcon

2425

Web 应用程序的 XP 风格面板栏。

XP panel bar in action..

引言

Windows XP 用户已经熟悉了出现在 Windows 资源管理器左侧的面板栏。 本文介绍了在 Web 应用程序中模仿此用户界面的另一种方法。 本文的灵感来自于 CodeProject 上另一篇很棒的文章 Windows XP 风格菜单。 但是,本文中提出的想法大量使用表格来格式化面板栏内容,并且还提供了一种在运行时更改样式表的方法。

面板栏布局

下图显示了面板栏中单个项目的 HTML 布局。 面板栏中的每个其他项目都遵循完全相同的布局。

HTML layout of panel bar...

  • 整个面板栏被包裹在一个 div 标签中。
  • 实际的面板栏由两个 div 标签形成。 主要是 HeaderLinks
  • 标题被渲染为一个单行 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 函数接受以下六个参数

  1. 指向要渲染链接项目的标题对象的引用。
  2. 要显示的链接文本。
  3. 链接 URL。
  4. 通过查询字符串传递给链接 URL 的额外数据。
  5. 要为链接显示的工具提示文本。
  6. 要在链接文本之前渲染的图像文件的名称。
  7. 最后,链接应该打开的目标 windowframe 名称。

setTheme 基本上允许菜单自定义。 它接受以下三个参数

  1. 自定义 CSS 文件的名称。
  2. 包含自定义主题文件的文件夹的相对路径和名称。 默认值为 CSS
  3. 包含自定义主题中使用的图像的文件夹的相对路径和名称。 默认值为 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 成员,负责渲染此子项。 此成员从 MenuBanddrawMenu 成员调用。

/**********************
 * 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.
}

绘图函数

面板栏构造中两个最重要的函数是 drawMenudrawSubMenu。 顾名思义,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日
    1. 支持单个面板的背景图像。
    2. 支持多个面板实例。
© . All rights reserved.