JQuery_ Novice to Ninja - Earle Castledine [61]
Once the delay expires it looks for a menu item containing the waiting class (which will only exist if the user hasn’t moved the mouse away). If the user is still waiting, we “click” the menu item, causing the effect to fire. This is the first time we’ve seen the click action used in this way; when called without parameters, it actually fires the click event on the targeted element(s), rather than setting up an event handler. Finally, once we fire the effect we remove the class—so we’re back to square one. We also need to modify the click action we defined earlier. As it is, if a user mouses over a menu and then clicks it, the waiting class will cause it to close when the timer goes off. We simply need to add the same removeClass call to the click handler.
What we’re doing—and we’ve done this before with earlier effects—is use classes to provide state management. State management is just a fancy way of saying we provide the control with a way of remembering what “state” it is in. We want to remember if the user has moved away from the menu before the delay expires— so we add and remove the waiting class appropriately. Using class names for state management is a nifty trick—but it’s certainly not the only (or best) way. We’ve already seen the data functionality provided by jQuery, which is a great way to store simple state information. For larger and more complex controls, we can also integrate state management into the widget’s code—as we saw at the end of Chapter 4. As always, the method you use is dependent on the circumstance, and on what feels simplest to you.
Drop-down Menus
If you ever had to code a drop-down menu in the old days of the Web (using what was at the time referred to as DHTML), you’ll know just how harrowing an experience it can be. There’s an abundance of terrible scripts lingering online from those days but, thankfully, CSS has since stepped in to banish reams of JavaScript spaghetti code to the trash heap. The Suckerfish Drop-down technique, and subsequent derivatives, provide an elegant solution to the problem of drop-down menus.
Suckerfish drop-downs work by carefully styling a list of lists into a drop-down structure, and then hiding the child menu items. The style sheet uses a :hover pseudo-selector to trigger the showing and hiding of the child items. This is a perfect JavaScript-free solution; as much as we love JavaScript, we should always aim to use simpler technologies such as CSS when they’re suitable.
That said, there are some issues with using pure CSS drop-down menus. Some older browsers are unable to style the :hover pseudo selector on non-link elements, and even for those that can, the showing/hiding effect can be a little abrupt. The Suckerfish drop-downs make an excellent base for enhancement: they provide an adequate solution, which can then be improved and streamlined with jQuery. In this example, we’ll be adapting the Suckerfish technique to work with browsers that have incomplete support for :hover. We’ll also make the drop-down effect a little sleeker with some jQuery animation.
Cross-browser Suckerfish Menus
First, let’s set up a simple Suckerfish drop-down as our baseline. We’ll be using the same markup we used for the expandable navigation in the section called “Expandable/Collapsible Menus”.
The CSS is straight out of the Suckerfish playbook, and will mold the unordered list into a simple horizontal menu. The only additional aspect to pay attention to is the extra class we’ve attached to the :hover CSS declaration. We’ll need this to keep our menu drop-down visible when it otherwise wouldn’t be:
chapter_05/05_dropdown_menu/menus.css
#container {
position: relative;
}
#menu {
position: absolute;
top: 0;
right: 0;
}
#menu, #menu ul {
padding: 0;
margin: 0;
list-style: none;
}
#menu li {
float: left;
background: #FFF;
}
#menu a {
display: block;
padding: 4px;