Sasha Vodnik
Sasha Vodnik

Reputation: 195

adding jQuery focus and blur to menu for accessibility

I've created a simple drop-down menu using jQuery. It works fine in response to the hover event. I also want it to respond to the focus and blur events to support keyboard users. The events are bound to a elements, and I've added tabindex values to the a elements for browser compatibility. However, the menus don't open when the main elements get keyboard focus.

HTML:

  <ul class="mainmenu">
     <li><p><a href="#" tabindex="1">Cruises</a></p>
        <ul class="submenu">
           <li><a href="#">Whale watching</a></li>
           <li><a href="#">Birding</a></li>
           <li><a href="#">Dinner</a></li>
           <li><a href="#">School field trips</a></li>
        </ul>
     </li>
     <li><p><a href="#" tabindex="2">Rates</a></p>
        <ul class="submenu">
           <li><a href="#">Children (0-17)</a></li>
           <li><a href="#">Adults</a></li>
           <li><a href="#">Seniors (60+)</a></li>
           <li><a href="#">Groups</a></li>
        </ul>
     </li>
     <li><p><a href="#" tabindex="3">Directions</a></p>
        <ul class="submenu">
           <li><a href="#">From the north</a></li>
           <li><a href="#">From the south</a></li>
           <li><a href="#">From the east</a></li>
        </ul>
     </li>
  </ul>

jQuery:

function display() {
   $(this).children("ul").show();
}

function hide() {
   $(this).children("ul").hide();   
}


$(function(){
   $("ul.mainmenu li").hover(display,hide);
   $("ul.mainmenu li a").focus(display);
   $("ul.mainmenu li a").blur(hide);
});

Any tricks to binding to the hover event that I'm missing?

Fiddle: http://jsfiddle.net/shameless/bw6GJ/

Upvotes: 1

Views: 1620

Answers (1)

haim770
haim770

Reputation: 49125

Try this:

function display() {
   var $this = $(this)
   var $ul = $this.children("ul");

   if (!$ul.length)
        $ul = $this.parents('li:first').children('ul');

   $ul.show();
}

function hide() {
   var $this = $(this)
   var $ul = $this.children("ul");

   if (!$ul.length)
        $ul = $this.parents('li:first').children('ul');

   $ul.hide();   
}

The problem is that when the display/hide functions are being fired for the focus/blur event, the function context is the <a> element, hence the this keyword in your function refers to the wrong element and not to the parent <li> (as in hover) as you intended.

Upvotes: 3

Related Questions