打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
门户菜单和窗口控件
在 Internet Explorer ( IE ) 中 , 以重叠方式动态放置 HTML 元素 , 可能导致一些元素隐藏另外一些元素。不幸的是 , BEA WebLogic Portal 8.1 中 , 在包含特定 HTML 实体 ( 如 SELECT 元素或 ActiveX 控件 ) 的门户页面上使用多层菜单时 , 此事就有可能发生。讨厌的结果是,菜单可能会被部分隐藏。本文介绍了解决这一问题的 HTML 技巧,即确保在门户页面上,把菜单显示在所有其他元素之上的技巧。

简介

  通过使用 DHTML effects , 有选择地显示或隐藏 HTML 页面的一部分 , 往往可以用来创建在 HTML 中动态显示的菜单。 WebLogic Portal 创建菜单使用的技巧是,将菜单项包围在标准的 HTML DIV 元素中。这些元素是通过嵌入在页面,以及JavaScript 支持 文件(如 menu.js )中的 JavaScript 代码,来打开和关闭的。下面是显示方式的简单示例:

<DIV id=‘menu1Title‘ onClick=‘toggle("menu1")‘>File</DIV><DIV id=‘menu1‘>    <DIV id=‘menuItem1‘>Open</DIV>    <DIV id=‘menuItem2‘>Close</DIV>    <DIV id=‘menuItem3‘>Exit</DIV></DIV>

  上面是一个很标准的例子 , 一般来说 , 门户开发人员没有必要知道这一底层实现机制。但是,有些浏览器极不稳定,从而导致上述技巧出现问题。在 Mozilla 和 Firefox 中运行正常的解决方案,在 IE 中使用时却会产生问题 , 原因在于处理窗口控件的 IE 工件。

  窗口控件 是 Windows 开发人员使用的一个术语 , 指的是具有窗口句柄的控件 ( HWND ,为您这样的 Win32 高手提供 ) 。这些控件由操作系统来管理和实施 , 而不是浏览器。 Microsoft 创建 IE 时,选择使用了现有的组合框(窗口控件)的 Windows 实现工具作为 HTML SELECT元素的实现工具。此外 , 其他嵌入式对象 ( 包括 ActiveX 、 Flash 和 Adobe PDF 查看器 ) 也都是作为窗口控件来现实的。

  本文的目的在于,您不必了解句柄和 Win32 ,但是需要认识到,一旦操作系统(而非浏览器)管理了窗口控件,基于窗口控件的 HTML 元素,就可能具有了与规则 HTML 元素不同的字符。

出现的问题

  简单地说 , 在 Web 页面中动态放置和显示 DIV 元素时,窗口控件就成了 IE 中长期存在的问题根源。尤其是,窗口控件在通过 DIV 显示时,将破坏预期的效果。 这一点在使用 DIV 元素显示菜单的 Web 页中尤为明显,遗憾的是,这一问题严重地影响着 WebLogic Portal 中的菜单,如图 1 所示。


图 1 : 窗口控件隐藏下拉菜单

  在此图中 , 第一个 portlet 中的各种框遮盖了下拉菜单 , 结果导致菜单无法有效使用。如大多数 HTML 开发人员所知道的那样,在浏览器中,分层的 HTML 元素的显示是由 zIndex 属性来控制的。具有较高 zIndex 的元素显示在具有较低 zIndex 的元素的上面。问题产生的原因是, IE 对 HTML 元素的 zIndex 和窗口控件的 zIndex 的处理方式不同,它总是将窗口控件置于所有 HTML 元素的上面。这可能导致无法将 DIV 显示在 SELECT 上面 , 而不是让 SELECT 穿过 DIV 显示。

  此问题在 DHTML zIndex 属性的 MSDN documentation 中已有介绍 , 其中明确阐述了 zIndex 属性并不支持窗口控件。

解决方案

  在 IE 5.5 及其更高版本中,解决此问题极为简单 , 因为它们具有相当新的 JavaScript 技巧,如对 IFRAME 元素行为的更改。在 IE 5.5 及其更高版本中 , IFRAME 元素的 zIndex 同时考虑到了窗口控件和 HTML 元素。这意味着,用户可以将 IFRAME 置于 SELECT之上,它将遮盖 SELECT 窗口控件。此外,还可以将 DIV 覆盖在 IFRAME的上面,它所遮盖的 IFRAME 或 SELECT 都将不再显示。

  这一特殊的 IFRAME 被 置于 DIV 的 下面以隐藏窗口控件 ,它被 称为 垫片 , 因为它仅用于遮盖 DIV 。许多资料都讨论了如何使用此技巧,在下述参考部分中,我们重点介绍其中之一。除此之外,在 MSDN 文档资料中,还包括了对 IFRAME 元素的 zIndex 属性的行为更改。

在 WebLogic Portal 中使用垫片技术

  现在我们了解了垫片技术 , 我们需要将其应用于 WebLogic Portal 菜单。幸运的是, WebLogic Portal 中的菜单是由 JavaScript 生成的,因此我们将垫片用于菜单极为方便。只需要修改一个文件(menu.js)即可,该文件位于 framework/skins/default/js 目录中。证明 menu.js 是如何显示菜单的,超出了本文讨论的范围,但是关于此过程的详细信息可以在 WebLogic Portal User Interface Framework Guide 中找到。

  首先我们需要进行的修改是,添加所有新的垫片功能 , 以便根据需要创建、显示和隐藏这些垫片。注意,因为当用户通过各子菜单下溯时 WebLogic Portal 会 同时显示出很多菜单,所以我们需要具有创建和显示多个垫片的能力。从本质上说,在垫片和每个菜单之间存在着一一对应的关系。创建每个垫片时 , 它都具有一个同与之关联的菜单相对应的标识。

  不幸的是 , 因为在 WebLogic 服务包之间 , menu.js 可能发生变更 ,所以 提供经过修改的 menu.js 是不可行的。反之,要应用此解决方案,用户需要手动修改 menu.js 文件,但是请放心,这是一个很简单的任务。

  第一个步骤是将那些基本的 JavaScript 功能,添加到以后打开和关闭菜单时将要引用的文件中。这些功能如下所示,将这些功能附加在 menu.js 的结尾处即可。

//Opens a shim, if no shim exists for the menu, one is createdfunction openShim(menu,menuItem){    if (menu==null) return;    var shim = getShim(menu);    if (shim==null) shim = createMenuShim(menu,getShimId(menu));        //Change menu zIndex so shim can work with it    menu.style.zIndex = 100;        var width = (menu.offsetWidth == 0 ? menuItem.renderedWidth : menu.offsetWidth);    var height;        if (menu.offsetHeight == 0)    {        var menus = getMenuItemCount(menu);        height = menuItem.renderedHeight * menus;    }    else    {        var height = menu.offsetHeight;    }        shim.style.width = width;    shim.style.height = height;    shim.style.top = menu.style.top;    shim.style.left = menu.style.left;    shim.style.zIndex = menu.style.zIndex - 1;    shim.style.position = "absolute";    shim.style.display = "block";}//Closes the shim associated with the menufunction closeShim(menu){    if (menu==null) return;    var shim = getShim(menu);    if (shim!=null) shim.style.display = "none";}//Creates a new shim for the menufunction createMenuShim(menu){    if (menu==null) return null;    var shim = document.createElement("<iframe scrolling=‘no‘ frameborder=‘0‘"+                                      "style=‘position:absolute; top:0px;"+                                      "left:0px; display:none‘></iframe>");     shim.name = getShimId(menu);    shim.id = getShimId(menu);    //Unremark this line if you need your menus to be transparent for some reason    //shim.style.filter="progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=0)";    if (menu.offsetParent==null || menu.offsetParent.id=="")     {        window.document.body.appendChild(shim);    }    else     {        menu.offsetParent.appendChild(shim);     }    return shim;}//Creates an id for the shim based on the menu idfunction getShimId(menu){    if (menu.id==null) return "__shim";    return "__shim"+menu.id;}//Returns the shim for a specific menufunction getShim(menu){    return document.getElementById(getShimId(menu));}function getMenuItemCount(menu){    var count = 0;    var child = menu.firstChild;    while (child)    {        if (child.nodeName=="DIV") count = count + 1;        child = child.nextSibling;    }    return count;    }

  将这些新功能粘贴到 menu.js 的底部后 , 下一个步骤是将这些新功能应用于各种菜单功能中。第一个要更改的功能称为openMenu()。如果在menu.js中搜索它,则可以看到它带有三个参数:menuItem、menu和depth。在此,您需要做的只是在该方法的结尾处添加一个新的代码行:

openShim(menu,menuItem);

  注意 , 此为对我们先前添加的一种功能的调用。它的作用是,确保每次打开菜单时创建和显示垫片。

  下一个修改是 , 确保在关闭菜单时关闭垫片。为此,需要修改menu.js中的closeAllChildren()方法。尤其是,需要在该方法中添加一个行;首先在该方法中查找此现有行:

subMenu.style.display = "none";

  在此行的后面 , 添加一个关闭垫片的新行 :

closeShim(subMenu);

  注意 , 这一行也是对我们先前粘贴的一种功能的调用。

  恭喜 ! 您已经完成的修改。如果没有什么差错 , 则在 IE 5.5 和更高版本中 , 您的 WebLogic Portal 菜单现在应该正常运行了 , 如图 2 所示。


图 2 : 正确覆盖底层窗口控件的菜单

结束语

  本文阐明了通过 Internet Explorer 呈现页面时 HTML 元素有时被其他 DHTML 元素隐藏的问题。我们介绍了使用IFRAME垫片方便地解决此问题的方式,并演示了如何修改 WebLogic Portal 以利用此解决方案的方法。结果形成了提高门户外观并增强用户满意程度的解决方案。

参考资料

关于作者

Gerald Nunn 是 BEA 系统专业服务的业务主任顾问

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Portal Menus and Windowed Controls
怎么样在当前网页包含另外一个页面代码
VBA自定义菜单和菜单栏
动态菜单(二)
用iframe解决Applet遮挡菜单
20.4.2 添加RibbonX到内置选项卡 - 51CTO.COM
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服