JavaScript Rollovers: Maximum "Transition" Quality - Doc JavaScript | WebReference

JavaScript Rollovers: Maximum "Transition" Quality - Doc JavaScript


Maximum "Transition" Quality

Try pointing at the "Hebrew" button and then slowly moving the pointer to the "Contact" button. During this time, pay close attention to the "Packages" button, which is the default button. The moment you move from "Hebrew" to "Contact", the "Packages" button flashes (it's too fast to see exactly what it does). Why does that happen? When you move the mouse from the "Hebrew" button to the "Contact" button, the "Hebrew" button's onMouseOut event handler is triggered, so the "Packages" button becomes active (it's the default button). At the exact same time (or a millisecond later) the "Contact" button's onMouseOver event handler is triggered, making the "Packages" button inactive. Within one millisecond, the "Packages" button becomes active and then inactive again.

We'll improve our rollover menu by preventing this distracting side effect. First, take a look at the new version of actMenuItem() and inactMenuItem():

var isMenuAct = false; // the menu is not active yet
function actMenuItem(imgName) {
  isMenuAct = true; // the menu is now active
  act(imgName);
  inact(defImg);
}
function inactMenuItem(imgName) {
  isMenuAct = false; // the menu is no longer active
  if (document.images) {
    inact(imgName);
    timerID = setTimeout('if (!isMenuAct) act("' + -->
defImg + '")', 1);
  }
}

We use the built-in setTimeout() function to suspend the following action by one millisecond. That is, after one millisecond, if the menu is still not active, the default image (the "Packages" button in our examples) becomes active. If the user moves the pointer from the "Hebrew" button to the "Contact" button, for instance, the "Contact" button's onMouseOver event handler invokes the actMenuItem() function, which assigns true to the variable isMenuAct (because the menu is now active).

Thus, the "Hebrew" button's onMouseOut event handler, which invokes the inactMenuItem() function, does not activate the "Packages" button (thanks to the time delay). Let's see what event handlers the default image should have:

<A HREF="packages.html"
   onMouseOver="isMenuAct = true; act('pack')">
<IMG SRC="packon.gif"
     HEIGHT="26"
     WIDTH="100"
     NAME="packr"
     ALT="Packages"
     BORDER="0"></A>

The onMouseOver event handler assigns true to the isMenuAct variable and then activates the "Packages" button. If we omitted this event handler, the script would work fine, but it would take one millisecond for the "Packages" button to become active when the user moves the pointer to the "Packages" button. This event handler ensures that the "Packages" button becomes active immediately. Here's the final menu:


Home
Advantages
Packages
Hebrew
Contact

Note that this script can be written in many ways. For example, instead of executing a set of statements if document.images is supported, you could simply terminate the function if document.images isn't supported. Here's an example:

function inactMenuItem(imgName) {
  if (!document.images) return;
  isMenuAct = false; // the menu is no longer active
  inact(imgName);
  timerID = setTimeout('if (!isMenuAct) act("' + -->
defImg + '")', 1);
}

As a general rule, you should try to avoid using unnecessary variables. The following functions operate properly without utilizing isMenuAct like before:

var timerID = null;
function actMenuItem(imgName) {
  if (timerID) clearTimeout(timerID);
  act(imgName);
  inact(defImg);
}
function inactMenuItem(imgName) {
  inact(imgName);
  timerID = setTimeout('act("' + defImg + '")', 1);
}

The inactMenuItem() function sets a timeout to invoke act() after one millisecond. In other words, it instructs the browser to activate the default image after one millisecond. If the user removes the pointer from the menu, the default image is activated as expected.

If the user moves the mouse to another image in the menu, the onMouseOver event handler of the new image calls actMenuItem(), which cancels the timeout set by the previous image's onMouseOut event handler. The conditional statement checks if a timeout really exists before sending it to clearTimeout() (a built-in function). Notice that the timeout identifier, timerID, must be defined beforehand, in order to avoid an error when actMenuItem() is called for the first time. Once again, let's see what event handlers the default image should feature:

<A HREF="packages.html"
   onMouseOver="if (timerID) clearTimeout(timerID); -->
act('pack')">
<IMG SRC="packon.gif"
     HEIGHT="26"
     WIDTH="100"
     NAME="packr"
     ALT="Packages"
     BORDER="0"></A>

Created: August 21, 1997
Revised: March 30, 1998

URL: http://www.webreference.com/js/column1/transition.html