I have a full-width drop-down menu that shows all submenu's on hover or on getting focus (to make it keyboard-accessible). It's a menu you see often, but keyboard accessibility I haven't found examples of implemented in a way that it simulates the hover-behaviour (in other words: expanding the menu).
Here's the HTML of the menu:
<div id="menu">
<div class="container">
<ul class="row">
<li class="first"><a href="link">Home</a></li>
<li><a href="link">Projects</a>
<ul class="inner">
<li class="first"><a href="link">Project 1</a></li>
<li class="last"><a href="link">Project 2</a></li>
</ul>
</li>
<li class="last"><a href="link">Contact</a>
<ul class="inner">
<li class="first"><a href="link">Visit us</a></li>
<li class="last"><a href="link">Email</a></li>
</ul>
</li>
</ul>
</div>
</div>
I've been trying all kinds of ways to make this work with Jquery (still learning Jquery), and it works partially. The hover feature works kind of, still some strange things happening. The problem is with the focus/blur function. I've added a timeout to the blur function, otherwise it will fire every time I tab to another link. But with this timeout in place, the blur effect doesn't happen anymore. (the menu stays expanded).
What might make this different from other solutions is that I want the hover, focus and blur event to happen on the #menu div, not on individual links. I want it to work this way because it's a full width menu, you see all submenus at once when hovering the menu. I found out that adding 'tabindex = 0' to the div makes it possible to use focus and blur. Therefore I decided to add this by Jquery as well.
My Jquery looks like this:
$(document).ready(function() {
/* dropdownmenu */
$("#menu")
.attr("tabindex",0)
// HOVER
.hover
( function ()
{
$(this).addClass('dropdown');
$(this).animate({ height: '20em'});
},
//hover out
function()
{
$(this).animate(
{ height: '6em' },
{ complete: function() { $(this).removeClass('dropdown'); } }
)
}
)
// FOCUS
.focus
( function ()
{
$(this).addClass('dropdown');
$(this).animate({height: '20em'});
}
)
// BLUR
.blur
( function()
{
setTimeout(function()
{
$(this).animate(
{height: '6em'},
{ complete: function() { $(this).removeClass('dropdown'); } }
)
},500);
}
);
I hope someone can help me a little to make this Jquery better. Is it way to long? And why is the hover function acting strange and the blur function not working at all? Should I go about this another way?
I also added this in jsfiddle: http://jsfiddle.net/CpdM2/1/ The heights are different here to demonstrate the behaviour better.
Thanks for any help!
EDIT
I'm now trying a different approach with the Jquery. I'm getting closer, the only problem remains with the blur function.
My new jquery:
$.fn.accessibleDropDown = function ()
{
var el = $(this);
$(el).mouseenter(function() {
$("#menu").addClass('dropdown');
$("#menu").animate({ height: '7em'});
}).mouseleave(function() {
$("#menu").animate(
{ height: '1em' },
{ complete: function() { $("#menu").removeClass('dropdown'); } }
);
});
/* Make dropdown menus keyboard accessible */
$("#menu").focus(function() {
//alert("focus");
$("#menu").addClass('dropdown');
$("#menu").animate({ height: '7em'});
}).blur(function() {
setTimeout(function() {
if ($('#menu').find(':focus').length > 0) {
return false;
} else {
alert("menu does not have focus");
$("#menu").animate(
{ height: '1em' },
{ complete: function() { $("#menu").removeClass('dropdown'); } }
);
}
}, 50);
});
};
$("#menu").attr("tabindex",0).accessibleDropDown();
See it in action here: http://jsfiddle.net/kBNRv/
The code to see if the #menu div has lost focus is for some reason not working. I really hope someone can point me in the right direction. Thanks in advance.