How to set focus on first focusable element jQuery?
Asked Answered
S

4

15

I've been working on a dropdown/popup menu, and I have it working great, with one exception; when you click on the link (or hit the enter key) to open the menu, focus is supposed to be set to the next element that can receive focus. So in this example, clicking on the "Menu 1" link, should expand the menu, and set focus on "test 1". But for some reason, it jumps to the last focusable element (test 3) instead:

<ul class="axxs-menu">
  <li><a class="trigger">Menu 1</a>
    <ul class="content">
      <li><a href="#1">test 1</a></li>
      <li><a href="#2">test 2</a></li>
      <li><a href="#3">test 3</a></li>
    </ul>
  </li>
</ul>

Here is the relevant js:

jQuery.extend(jQuery.expr[':'], {
    focusable: function(el, index, selector){
    return $(el).is('a, button, :input, [tabindex]');
}
});

function openPopmenu(element) { 
$(element).removeClass('trigger-inactive').addClass('trigger-active').attr("aria-expanded", "true").attr("aria-selected", "true");
 $(element).next('.collapsed').removeClass('collapsed').addClass('expanded').show().attr("aria-hidden", "false");
$(element).next().find(':focusable').focus();
}

And here is a code pen:

http://codepen.io/tactics/pen/EZbGBY

Any help is much appreciated.

Schoolfellow answered 29/1, 2017 at 1:38 Comment(0)
V
14

This statement $(element).next().find(':focusable').focus(); will look for all elements with the focusable attribute and returns the last one. What you want to do is limit it to a particular one which is the first. You can use the .eq() function which specifies the actual index you want like this

$(element).next().find(':focusable').eq(0).focus();

Vinegarette answered 29/1, 2017 at 2:0 Comment(2)
Uncaught Error: Syntax error, unrecognized expression: unsupported pseudo: focusable at Function.fa.error (jquery.min.js:2) at PSEUDO (jquery.min.js:2) at wa (jquery.min.js:2) at fa.compile (jquery.min.js:2) at fa.select (jquery.min.js:2) at Function.fa [as find] (jquery.min.js:2) at n.fn.init.find (jquery.min.js:2) at openTab (scripts.js:51) at HTMLAnchorElement.<anonymous> (scripts.js:30) at HTMLAnchorElement.dispatch (jquery.min.js:3) Doesn't seem to work for me...Sgraffito
:focusable is not part of jQuery, rather jQuery UI.Kana
B
10

The :focusable psuedo selector is only available with jquery-ui. If your only using jquery then replace '.find(':focusable') with the following:

.find('button, a, input, select, textarea, [tabindex]:not([tabindex="-1"])')

Bumf answered 26/7, 2019 at 19:1 Comment(0)
G
4

A little improvement for Drews answer, since input type hidden is not focusable and should be excluded. So replace ".find(':focusable')" with this:

.find('button, a, input:not([type="hidden"]), select, textarea, [tabindex]:not([tabindex="-1"])')
Grizel answered 27/5, 2021 at 11:30 Comment(0)
O
3

What you need is to find the first focusable element:

$(element).next().find(':focusable').first().focus();

Without .first(), focus() is applied to all the elements matching :focusable, which eventually ends up focusing the last element.

Optimism answered 29/1, 2017 at 2:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.