First and foremost, Marc, thanks bunches for responding and for pointing out my typo = :focus
versus .focus()
.
To continue, it is apparent that I need to expand my description to include a bunch more code.
(In deference to citing the whole truth, the general idea behind all this wordy code came from elsewhere … not every specific, but the general approach belongs elsewhere)
My apologies in advance to your fatigued eyes for the length.
-
my goal is to implement cycling of TAB keypresses, i.e., when I focus (via shift-TAB keypress) on the 1st element, I call .focus() on the last element and when I focus (via TAB keypress) on the last element, I call .focus() on the 1st element.
-
Here is my element layout:
li1#cycleAtFirstMenu li2#first li3 li4 ... liN.#last li#cycleAtLastMenu
- in my .html markup I have:
<body onload="addFocusToLIs(); setupTabKeyToNextLI(); setupTabCycleFirst(); setupTabCycleLast(); setInitialFocus()">
followed by:
<ul>
<li id="cycleAtFirstMenu">
<!-- deliberately empty -->
</li>
<li id="first">
<!-- stuff -->
</li>
<!-- other li's -->
<li id="last">
<!-- stuff -->
</li>
<li id="cycleAtLastMenu">
<!-- deliberately empty -->
</li>
</ul>
</body>
- Here’s my addFocusToLIs() which makes every
<li>
focusable:
function addFocusToLIs() {
$(document).ready(function() {
$("li").each(function() {
$(this).attr("tabindex", 0);
});
});
}
- Here are the 2 setupTabCycle()‘s’:
// going backwards via shift-TAB (counter-clockwise)
function setupTabCycleFirst() {
$(document).ready(function () {
$("#cycleAtFirstMenu").on('focus', function (evt) {
$("li#last").focus();
});
});
}
// going forward via TAB (clockwise)
function setupTabCycleLast() {
$(document).ready(function () {
$("#cycleAtLastMenu").on('focus', function (evt) {
$("li#first").focus();
});
});
}
- Here’s my Event Loop:
function setupTabKeyToNextLI() {
$(document).ready(function() {
$(document).keyup(function (evt) {
var code = evt.keyCode || evt.which;
if (evt.shiftKey && code === 9) {
showMenuWithTAB(kBackward); // = -1
evt.stopPropagation();
}
else if (code === 9) {
showMenuWithTAB(kForward); // = 1
evt.stopPropagation();
}
});
});
}
- Finally, here’s my setInitialFocus:
function setInitialFocus() {
$("li#cycleAtFirstMenu").focus();
}
I have deliberately revealed setInitialFocus at the last of this wordy reply because I just do not understand why it works … that is, why does $("li#cycleAtFirstMenu").focus();
not trigger the .on("focus"
within setupTabCycleFirst()
.
Granted, I don’t want it to … I just want setInitialFocus()
to simply select li#cycleAtFirstMenu
so when I press my 1st TAB key, showMenuWithTAB(..)
is called:
(Note: since setupTabKeyToNextLI()
pegs on .keyup
, $currItem
= the next li
with a tabindex=0
)
function showMenuWithTAB(..) {
var $currItem = $(document.activeElement);
// stuff
}
Again, everything works the way I want. But, that seems to indicate that calling setInitialFocus()
within body’s onload=""
does not trigger the .on("focus", ...)
part of my Event Loop within my 2 setupTabCycle's
.
Maybe it’s a calling order within <body onload="">
? I just do not know.
FWIW, I did read somewhere that only clicking on an element and TABbing to it causes focus … dunno! At least, if true, that would indicate that the out-of-the-blue, stand-alone call (without a preceding TAB keypress) to .focus() within setInitialFocus()
just selects, but doesn’t trigger anything else.
Again, Marc, my apologies to your fatigued eyes for the length.