Bookmark and Share

The DOM Event Model

Review the W3C DOM2 Event standard recommendation.

Because mouse events are always targeted at the most deeply nested element underneath the mouse pointer. In this case, mouseout events are fired for the menu item's A tags as you move the mouse over them. These bubble back up to the menu DIV tag where they trigger the handler set for it, calling closeMenu() which hides the menu.

To get around this, code has to be added to closeMenu() to determine where the mouse is moving to. If it's moved onto an element within the menu DIV, it should ignore the event. Only when it moves onto an element outside the menu DIV should it hide the menu.

Here's an update version of closeMenu() which checks the Event object to find out what element the mouse has moved onto:

function closeMenu(event) {

  var current, related;

  if (window.event) {
    current = this;
    related = window.event.toElement;
  else {
    current = event.currentTarget;
    related = event.relatedTarget;

  if (current != related && !contains(current, related))
    current.style.visibility = "hidden";

The variable related is set to the element that the mouse is moving onto while current is always the menu DIV itself. If the related element is the menu DIV itself or is nested within the menu DIV, the event is ignored. Otherwise, the menu is hidden.

The function contains() has been added to determine if one element is nested inside another. The code looks like this:

function contains(a, b) {

  // Return true if node a contains node b.

  while (b.parentNode)
    if ((b = b.parentNode) == a)
      return true;
  return false;

You can try the modified version with the link below:

Open Menu

Now the menu behaves as desired, closing only when the mouse is moved completely off of it.


Now you should have a basic understanding of the DOM event model. While there are some pitfalls to watch out for, mostly caused by browser-specific implementations, you can use this information to code towards the standard model and work out individual differences between browsers with a minimum amount of coding.