fixing spastic menus…
Don’t you just love all those web sites with pull-down and fly-out menus that unexpectedly flash in your face when you don’t want them, and then disappear when you do want them? Let’s face it: our mouse movements are never perfect, and hover events need to take this into account to avoid irritating the user.
The easy fix is a neat little jQuery plug-in called hoverIntent, by Brian Cherne. What it does is add a little delay the mouseOver event, and optionally the mouseOut event, waiting until the user has definitely hovered, or un-hovered, the menu. In effect, it “eats” unintended mouse events. The effect is nice—no more flashing unexpected menus in your face, and no more menus that fly away while you’re trying to use them. Try it on the menu above and see the effects.
Using hoverIntent for WordPress Nav Menus
I’ve used hoverIntent before on hand-made sites, but recently I decided to put it in my WordPress site. But Not So Fast! The way WordPress builds pages has a rather steep learning curve. First of all, you can just edit the header.php file of your theme and put in the link to load the hoverIntent script, followed by some jQuery in a document.ready handler (just under wp_head() ) to make hoverIntent work on the desired menu, in the desired ways:
The Usual Way
Something like that will get it going, after you have disabled the :hover effects in the nav menu portion of your CSS file. But is that really the right way to do it in WordPress? Well… no.
The WordPress Way
WordPress has built-in ways of handling the dependencies and proper load-order of things, so we should do it the WordPress way, which is to make a couple functions in functions.php and then tell it to “enqueue” the hoverIntent script (that comes with WordPress), and also load the instantiation in the head section of the generated page to tell hoverIntent what to do.
I couldn’t find any applicable examples on-line, so after many hours of fiddling I ended up with this, which goes in functions.php in the template:
And that’s it! Assuming you already have a working CSS-based drop-down or fly-out menu in your header.php file, you don’t need to add anything else to it. WordPress will now load hoverIntent at the right place (and it will also load jQuery, if not already loaded). And when it runs wp_head() it’ll add your initialization script that ties hoverIntent to your nav menu.
- You need to study your document tree a bit to see what tags, IDs, and classes your nav menu uses, which will vary with different themes.
- You can’t use $ for jQuery in WordPress—it loads it in “noConflict” mode.
- Be sure your CSS (1) hides the sub-menu ULs on page-load, but (2) doesn’t show them on :hover, as that would override the effect and you’ll think it isn’t working.
- If you have not defined a custom menu in WordPress Admin, WP will use wp_page_menu() to build the menu when wp_nav_menu() is called. The menu will be built in levels according to the parent and menu order settings of all your pages.
- The hoverIntent “timeout” setting refers to the mouseOut delay, which defaults to 0, so you need to instantiate it as shown above to use timeout. 400 (milliseconds) is a decent setting to keep the menu open while you are navigating it and cutting corners along the way.
- Since we now have jQuery handy, we might as well add some nice animation to the menu. We could just use show() and hide(), but it’s much more pleasing to use slideDown() slideUp(), or fadeIn() fadeOut(), or even better, both! We could even use jQuery animate() to make the menu display in other neat ways by animating various CSS properties of the drop-down ULs.