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.

2002-05-31: First public version released.
2002-06-10: Updated rather a lot of code to fix flickering in IE55. Also some general optimization done.
2002-10-30: Version 4.2 - Lots of work to work around Internet Explorer memory leaks. Some new demos added as well.
2006-05-29: Changed license to Apache Software License 2.0.

Introduction

This is the next evolution in the DHTML Menu series. Where version 3 allowed menus to cover windowed controls version 4 can be displayed outside the physical boundaries of the browser window. Another major difference from previous version is that menus in version 4 are not defined using HTML markup. In DHTML Menu 4, menus are defined using JavaScript only. The menu system is totally object oriented and it takes the best parts from XMenu and earlier versions of the DHTML Menu.

Goals

Before the work started to develop version 4 a few goals were defined:

Implementation

There is quite a lot of code for DHTML Menu 4. In this section we will only touch the more interesting parts.

Popups

To be able to display a menu outside the browser window a so called popup object is used. Popups were introduced in IE55 and it is basically a window without any chrome around it. Even though popups allows you to display a document outside the browser its interface is very limited. It only has two methods and two properties.

Method/Property Name Description
show(x, y, w, h) Shows the popup at x,y using the size w,h. The position and size is modified so that it is never placed outside the screen.
hide() Hides the popup.
document Gives the document used inside the popup.
isShown Tells whether the popup is shown or not.

As you can see this is far from sufficient to do anything beyond the basics. But, there is one thing that the documentation at MSDN does not make clear and that is that the popup also contains a window object. To get the window object we can use oPopup.document.parentWindow. Now that we have the window object we can get the position of a popup. Besides from this there is another more important feature that the window object provides.

The most serious limitation of popups is that you can only have one popup visible at the same time. If you open up a new popup then the first one is closed. At least this is the first thing that strikes a lot of people when they are trying to use popups. To create a popup we have to use the method createPopup on the window object.

var p = window.createPopup();

The secret here is that you can only open one popup per window object and since we now know how to get the window used for the popup we can let the popup open up another popup.

var popup1  = window.createPopup();
var window2 = popup1.document.parentWindow;
var popup2  = window2.createPopup();

Menu Rendering

A menu is built up of a table where each row is a menu item. Each row constists of 4 cells; one for the icon, one for the text, one to show the keyboard shortcut and finally one to show an arrow indicating a sub menu.

The menu item has several methods that are used to create the HTML for the table row.

MenuItem.prototype.toHtml = function () {
   var cssClass = this.getCssClass();
   var toolTip = this.getToolTip();

   return "<tr" +
          (cssClass != "" ? " class=\"" + cssClass + "\"" : "") +
          (toolTip != "" ? " title=\"" + toolTip + "\"" : "") +
          (!this.visible ? " style=\"display: none\"" : "") +
          ">" +
          this.getIconCellHtml() +
          this.getTextCellHtml() +
          this.getShortcutCellHtml() +
          this.getSubMenuArrowCellHtml() +
          "</tr>";
};

As you can see, this method calls a lot of other methods that assembly the different parts of the HTML code. The reason for this is that it makes it easier to create subclasses because one only has to override a more specific method.

You can see a static version of the resulting HTML page here. This page might differ slightly from the current generated version but it should be exact enough for you to get a feel for what the HTML looks like.

ScrollButtons

To support scrolling a simple scroll button class was created. This class allows any element, when hovered, to scroll an element. This script can be used without the DHTML Menu 4 but it was designed with DHTML Menu 4 in mind.

When the mouse enters the button an interval is started. Every time this interval triggers the handler, the scrollable container is scrolled by updating the scrollLeft or scrollTop property.

There exists a scroll button demo that shows how these are used.

Positioning

The most common task in DHTML is once again needed. This time it was much easier than usual because only support for IE was needed. A minor new feature was needed for this and that was the ability to find the location of an element relative to the screen. To achieve this the location relative to the window viewport is first calculated and then the location of the window is added using window.screenLeft.

getScreenLeft:	function ( el ) {
   return el.document.parentWindow.screenLeft + this.getLeft( el ) +
      (this.getIeBox(el) ? 0 : this.getClientLeft(  el.document.documentElement ) -
      el.document.documentElement.scrollLeft );
},

Introduction
Menu Creation
Menu Bar Creation
Usage
API
Customizing look & feel
Demos
Download

Author: Erik Arvidsson