-1

A little bg info: I'm working on making a website 100% navigable by keyboard/tabs, and I'm stuck on making the dropdown menus open up when tabbed through.

Here's what I have so far:

  <ul class="nav-wrap">

    <li class="nav-primary-pg"><a class="selected" href="/">Home</a>

    </li>

    <li class="nav-primary-pg parent-nav"><a href="/about-us/">About Us<b></b></a>
      <ul class="nav-secondary-pg">
        <li class="back"><a href="#"></a></li>
        <li class=""><a href="/about-us/knowledge-expertise">Knowledge &amp; Expertise</a>

        </li>


        <li class=""><a href="/why-bank/testimonials">Testimonials</a>

        </li>
      </ul>

    </li>

    <li class="nav-primary-pg last-nav-item parent-nav"><a href="/contact-us/">Contact Us<b></b></a>
      <ul class="nav-secondary-pg">
        <li class="back"><a href="#"></a></li>


        <li class=""><a href="/contact-us/application">Apply Now</a>

        </li>
        <li class=""><a href="/contact-us/quick-quote">Quick Quote</a>

        </li>
        <li class=""><a href="/contact-us/subscribe">Subscribe</a>
        </li>
      </ul>

    </li>

  </ul>

</section>

And for the jQuery:

$("a").each(function (i) { $(this).attr('tabindex', i + 1); });

$('.parent-nav > a').each(function(){
    $(this).focus(function() {
        $(this).parent().children(".nav-secondary-pg").show();
    });
});

Right now, all of my links are getting the tabindex correctly, and the secondary navigation is showing when the .parent-nav > a is focused. The problem is getting that function to end when the next .parent-nav > a is focused. What happens, is I end up with a page that looks like this as I tab through:

tabs

How do I kill the function when I reach the next instance in the .each()?

1 Answers1

1

First, target your focus event handler like $('.nav-wrap a') so that it includes all nav links. Then, in your focus event handler, you can check to see if any subnavs are currently open. Finally, check to see if the subnav you're currently in is the one that's open - if it's not, then close out the other subnav, and open the one you're currently in.

Also, you don't need to use .each() here, as you can just attach the event handler directly to the jQuery collection. And finally, prefer .on('focus'...) instead of `.focus(...) (here's why). So the end result would look something like:

$('.nav-wrap a').on('focus', function() {
    // find open sub nav (if it exists)
    var $openSubnav = $('.nav-wrap .nav-secondary-pg:visible');

    // find the subnav that you're currently in
    var $thisSubnav = $(this).closest('.parent-nav').children('.nav-secondary-pg');

    // if the subnav you're in is not already open,
    // close other subnav and open this one
    if (!$thisSubnav.is($openSubnav)) {
        $openSubnav.hide();
        $thisSubnav.show();
    }
});
Community
  • 1
  • 1
jbyrd
  • 5,287
  • 7
  • 52
  • 86
  • Unfortunately, that doesn't work. The goal is to be able to tab through the links in the subnav (`.nav-secondary-pg`), and once the instance of the `.parent-nav > a` loses focus, the dropdown goes away and I can't tab through its subnav. – Brittany Layne Rapheal Feb 17 '17 at 19:59
  • 1
    Ok, just updated the answer - I tested it locally and it works. – jbyrd Feb 17 '17 at 20:32
  • That nailed it. Thank you! And thank you for the explanation of why you did what you did. I tried to approach this a number of ways, and I think I was starting to overthink it. – Brittany Layne Rapheal Feb 17 '17 at 20:37
  • 1
    Glad to help! Btw - I just made one minor update to the code - changed `$('.parent-nav a')` to `$('.nav-wrap a')` so that a subnav closes when you tab to a top-level nav link that doesn't have a subnav. Also - feel free to upvote my answer :) – jbyrd Feb 17 '17 at 20:40