Licensed under the Apache Software License 2.0

This component may be obtained, modified and distributed free of charge for personal as well as commercial use. Please see the license for the complete terms and exact wording.

2007-08-19: Added support for safari (in hover mode) and IE 7.
2006-05-28: Changed license to Apache Software License 2.0.

This is a simple menu system designed to work in Internet Explorer, Mozilla and Opera. This does however lead to some limitations and I'm going to cover some these and see what can be done and how. If you are not interested in these you can go directly to the implementation description.

Static Content Model

Opera has a serious limitation when it comes to DHTML and that is that you cannot change the content at runtime. This means that you cannot add or remove nodes. It also means that you cannot modify a text node (no way to change the text). This means that we cannot add and remove menus at runtime. Everything needs to be created at load, therefore we use the old classical document.write to generate our content.

Element Boundaries

To get the element size in IE, Mozilla and Opera we use the MS proprietary properties called offsetWidth and offsetHeight. Even though IE before version 6 uses a non standard box model all three browsers return the border box size when using offsetWidth and offsetHeight. This means that the size includes paddings and borders.

Element Positions

Once again all browsers use the same properties but this time it is not equally easy since all of them treat them a little bit different. The properties to use here are offsetLeft, offsetTop and offsetParent. The difference is basically that Opera returns the position from the offsetParent's top left corner while IE and Mozilla returns the position from the upper left minus the borders. Another problem that is ignored when finding the positions for the XMenu is that any container may have been scrolled. If you want to take this into account you need to subtract the scrollLeft and scrollTop.

Window Size

All three browser do allow you to get the size of the document. Opera and Mozilla use window.innerWidth and window.innerHeight just like Netscape Navigator 4.x. In IE on the other hand we return the size of the root (canvas) element. This is normally the html element but if IE is in quirks mode (all versions prior to IE6 except IE5 Mac) this is the body.

Event Model

Only Mozilla supports the W3C standard way of hooking up events correctly but all three browsers almost support the event attributes on html identically. The big difference is that IE incorrectly binds the event object to the window object. The menu system does not need the event object because all elements pass all the desired arguments in the event attributes.

<a href="myuri" onmouseover="webFXMenuHandler.overMenuItem(this)">...</a>

Box Model

This is the biggest problem today when trying to create cross browser DHTML applications because Internet Explorer (before version 6) does not support the correct box model. CSS3 has a proposed property called box-sizing which currently have two possible values, border-box and content-box. Border box is what old versions of IE are using and content box is what CSS1 uses. Border box means that the width is calculated including the border and padding. Content box does not include the borders nor the padding. This gives Mozilla and Opera a wider box and therefore som extra properties are needed to make the layout identical in the different browsers.

There is a trick that can be used when defining the CSS for cross browser applications. IE5 added a proprietary value called expression which evaluates an expression and uses that value as the value for the property. All browsers with correct CSS support should ignore invalid CSS declarations so declarations done using expression are ignored. The following CSS declarations give the same look and feel in all three browsers.

.selector {
   border:  10px solid black;
   padding: 10px;
   width:   60px;
   width:   expression(ieBox ? 100 : 60 + "px");
}

Opera Focus Bug

The menu system uses the events onfocus and onfocus to show and hide the menus. This allows an easy way to make sure the menus are hidden with almost no code.

Opera does however not support focus on anchors so to get the menus to work in Opera the hover mode is used.

Introduction & Browser Issues
Usage
Implementation
API
Look & Feel
Hover Menu

Author: Erik Arvidsson