Online Book Reader

Home Category

JQuery_ Novice to Ninja - Earle Castledine [62]

By Root 1132 0

width: 10em;

}

#menu li ul {

position: absolute;

width: 10em;

left: -999em;

}

#menu li:hover ul, #menu li ul:hover {

left:auto;

}


If you try this on most browsers, you’ll be pleasantly surprised: a fully working menu system with no JavaScript! What we want to do now is layer some jQuery on top of this effect so that it functions in older browsers, and animates a bit more smoothly. Our target functionality is illustrated in Figure 5.3.

Figure 5.3. Our drop-down menu in action

So how do we replicate this effect using jQuery? “Simple,” you might scoff. “Just add a hover action with a slide-down effect.” And you’d be right: adding a simple hover function would give us the desired behavior, but there’s a problem. What happens when we implement the same functionality in both our CSS and our script? Who wins in the fight between CSS :hover and jQuery hover? It’s messy—they’re very evenly matched!

One obvious workaround would be to override the CSS class in our hover event handler. But this will fail, as you’re unable (currently) to target pseudo selectors in jQuery to set CSS properties:

$('#nav li:hover ul').css('left', '-999px'); // doesn’t work!


That puts us in a quandary: how can we keep the goodness of Suckerfish CSS menus, but still apply our jQuery enhancements? One solution would be to carefully undo the CSS properties as we hover—but an easier way is to take over the child menu item’s CSS properties, regardless of whether we’re hovering or not:

chapter_05/05_dropdown_menu/script.js (excerpt)

$('#menu li ul').css({

display: "none",

left: "auto"

});

$('#menu li').hover(function() {

$(this)

.find('ul')

.stop(true, true)

.slideDown('fast');

}, function() {

$(this)

.find('ul')

.stop(true,true)

.fadeOut('fast');

});


The first part of this script overrides the CSS we set earlier and hides the submenus using display: "none". When the user hovers over a list item, we find the related child list container and display it. Here we’ve used slideDown and fadeOut—but you’ll be able to come up with some wacky easing options and CSS background sprites to liven it up. The stop(true, true) command, as we saw in the section called “Animated Navigation” in Chapter 3, ensures that the menu will refrain from queuing up animations if we move the mouse around quickly.

The best aspect of this menu control is that when a user visits the site with JavaScript disabled, the Suckerfish drop-downs still work nicely—albeit without the animation effects.

Hover Intent

We’ve seen a few effects that are triggered by the mouseover event—and you may have noticed that they can sometimes feel a bit too eager to activate. The very instant you pass your mouse over a target element the effect springs to life, even if you’re just passing through. This is excellent for making fluid animated effects, but sometimes we’re after a different result. With our drop-down menus, the false start can appear unnecessary and distracting. We need a method of delaying the effect until we’re sure that the user really wants to activate the target element.

Earlier, we saw a method for achieving this by setting a timer when the user moves over the element. But this has a few side effects. For example, if you have a small timer and a large target area, the user might fail to make it all the way across the element before the timer expires.

Brian Cherne implemented a nice workaround for this issue, in the form of the Hover Intent plugin. Hover Intent has some smarts built into it to calculate the speed of the mouse as it moves across the elements. The effect will only kick in if the mouse slows down enough for the plugin to think the user intends to stop there.

Once you’ve included the plugin, you can use it wherever you’d normally use the hover action. As an example, if we wanted to add a delay to our drop-down menus from the previous section, we just need to replace the command hover with the command hoverIntent:

chapter_05/06_dropdown_with_hover_intent/script.js (excerpt)

$('#menu li').hoverIntent(function() {

}, function() {

Return Main Page Previous Page Next Page

®Online Book Reader