« | August 2025 | » | 日 | 一 | 二 | 三 | 四 | 五 | 六 | | | | | | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | | | | | | | |
| 公告 |
关注电子政务、大型企业应用开发、Web、Workflow、MOM、MDA、RCP、GEF email:gmluyang@gmail.com
|
Blog信息 |
blog名称:SixSun的Blog 日志总数:152 评论数量:372 留言数量:13 访问次数:2378706 建立时间:2004年12月13日 |

| |
[J2EE / EJB / JMS]门户菜单和窗口控件 网上资源
SixSun 发表于 2005/9/12 20:43:04 |
门户菜单和窗口控件
时间:2005-06-30作者:Gerald Nunn浏览次数:
366 本文关键字:DHTML, shim, windowed controls, portal menu, , WebLogic Portal 8.1
500)this.width=500'> 在 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 所示。
500)this.width=500'> 图 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 created
function 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 menu
function closeShim(menu)
{
if (menu==null) return;
var shim = getShim(menu);
if (shim!=null) shim.style.display = "none";
}
//Creates a new shim for the menu
function 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 id
function getShimId(menu)
{
if (menu.id==null) return "__shim";
return "__shim"+menu.id;
}
//Returns the shim for a specific menu
function 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 所示。
500)this.width=500'> 图 2 : 正确覆盖底层窗口控件的菜单
结束语
本文阐明了通过 Internet Explorer 呈现页面时 HTML 元素有时被其他 DHTML 元素隐藏的问题。我们介绍了使用IFRAME垫片方便地解决此问题的方式,并演示了如何修改 WebLogic Portal 以利用此解决方案的方法。结果形成了提高门户外观并增强用户满意程度的解决方案。
参考资料
MSDN DHTML zIndex property documentation
The IFRAME shim technique
WebLogic Portal User Interface Framework Guide
关于作者
Gerald Nunn 是 BEA 系统专业服务的业务主任顾问。
原文出处
http://dev2dev.bea.com/pub/a/2005/04/portal_menus.html
500)this.width=500'>
作者简介
Gerald Nunn是BEA Systems Professional Services的业务首席顾问。他已经结婚了,有一个4岁的儿子,生活在加拿大多伦多北部的纽马基特小镇。 |
|
|