Introduction

This is a small update to the XMenu system that allows the menus to be shown when the mouse pointer hovers a menu button and hides the menu when leaving it. For this to work I had to do some small changes and while I was at it I also removed the Opera focus bug hack because now you can get the menu to work in Opera using the hover mode.

Usage

There are three new global variables that control how the menu works.

Name Description
webfxMenuUseHover If this is set to true then the menu will be set in hover mode and this means that the menu will open on mouse over and hide on mouse out.
webfxMenuShowTime This is the time to wait before showing a menu. Using 0 when the menu is in hover mode is not recommended because then the menus will popup even when the user did not intend them to.
webfxMenuHideTime This is the time to wait before hiding a menu. When using normal mode it is important that this time is fairly large (~300ms) because otherwise the user will not have time to complete the click on the menu item she/he intended. When using hover mode this time should be about the same. If too small the menus will hide when going between sub menus.

These properties should be set (if changed) before the menus are written. The hover mode is only checked at creation.

webfxMenuUseHover = true;
webfxMenuHideTime = 500;
webfxMenuShowTime = 200;

Implementation

The main code for this was added to the webFXmenuHandler but throughout all the toString methods we had to test the hover mode and and add the inline event listeners accordingly. All these do is to call webfxMenuHandler.outMenuItem(this) (as well as the same for focus, blur and mouseover).

overMenuItem   :   function (oItem) {
   if (this.showTimeout != null)
      window.clearTimeout(this.showTimeout);
   if (this.hideTimeout != null)
      window.clearTimeout(this.hideTimeout);
   var jsItem = this.all[oItem.id];
   if (webfxMenuShowTime <= 0)
      this._over(jsItem);
   else
      this.showTimeout = window.setTimeout(function () { webFXMenuHandler._over(jsItem) ; }, webfxMenuShowTime);
},
outMenuItem   :   function (oItem) {
   if (this.showTimeout != null)
      window.clearTimeout(this.showTimeout);
   if (this.hideTimeout != null)
      window.clearTimeout(this.hideTimeout);
   var jsItem = this.all[oItem.id];
   if (webfxMenuHideTime <= 0)
      this._out(jsItem);
   else
      this.hideTimeout = window.setTimeout(function () { webFXMenuHandler._out(jsItem) ; }, webfxMenuHideTime);
},

The first thing to do in both over and out is to clear current timers. Once that is done we call the real code directly if no hide/show time or otherwise we call the code using window.setTimeout.

_over   :   function (jsItem) {
   if (jsItem.subMenu) {
      jsItem.parentMenu.hideAllSubs();
      jsItem.subMenu.show();
   }
   else      jsItem.parentMenu.hideAllSubs();
},
_out   :   function (jsItem) {
   // find top most menu
   var root = jsItem;
   var m;
   if (root instanceof WebFXMenuButton)
      m = root.subMenu;
   else {
      m = jsItem.parentMenu;
      while (m.parentMenu != null && !(m.parentMenu instanceof WebFXMenuBar))
         m = m.parentMenu;
   }
   if (m != null)   
      m.hide();   
},

The code in _over is exactly the same as we previously had in the original overMenuItem. The code for _out is fairly straight forward and all it does is to find the top most menu and if found hides it.

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

Author: Erik Arvidsson