Determining when tabbing beyond end of list

I use:

$(document.activeElement)

to return the current tabbed-to object.

Now, I need to know when I tab beyond the last tabbed-to object.

Note that each tabbable object is indicated with
.attr("tabindex", 0)

Just a hint would be nice, not the full-blown answer.

Here is what I have so far (2 approaches). Note that I have much more confidence in the 2nd approach, IF I could solve the line with “.find(…)”, which I know is wrong. I just do not know how to fix it.

function focusNextLI_1() {

	$(document).ready(function() {
		
		var $currFocusItem = getFocusedItem(), $nextFocusItem;
				
		if ($currFocusItem[0].length === 0) {
		//	alert("TAB after .last() is already showing");
		
			$nextFocusItem = $("li").first();
			$nextFocusItem.focus();
		}
		
	});

}   // focusNextLI_1


function focusNextLI_2() {

	$(document).ready(function() {
		
		var $currFocusItem = getFocusedItem(), $nextFocusItem;
		
		const $everyLI = $("li");
		const $currLI  = $everyLI.find($currFocusItem);   // ???
		
		$nextFocusItem = $currLI.next();
		if ($nextFocusItem.length === 0) {
		//	alert("TAB after .last() is already showing");
		
			$nextFocusItem = $everyLI.first();
			$nextFocusItem.focus();
		}		
		
	});

}   // focusNextLI_2


function getFocusedItem() {

	return $(document.activeElement);
	
}   // getFocusedItem

Are you perhaps wanting to find the index value of the item?
https://api.jquery.com/index/

Why would there by a focused item when the document becomes ready?

if the previous line worked, $currLI is the single element that corresponds to the currently focused item. There is no ‘next’ in this context; you’ve selected a single item, so the set of matched elements contains exactly 1 thing.

Paul’s correct, you want to use index; probably with a modulo, which will solve all your wrapping-around needs…

The issue with that approach is that $currFocusItem is a jQuery collection, and you probably want to check for the length of that instead of the first contained element (if there even is one).

Thanks everybody, in particular, Paul for his index citation.

Somewhere I found this quote “keypress events are fixed before the key is added to the $(document) queue … so the 1st keypress = blank.”

My goal is to TAB to successive <li>'s and when I detect li.daddy, for example, I know there’s a sub-menu that follows, so I want to immediately show the sub-menu.

I determine with TABing the selected <li> item with $(document.activeElement).

But, it appears that the response of $(document.activeElement) is actually the previously selected item.

This is validated by TABbing to li.daddy, for example. My code sees the <li> previous to li.daddy. Only after a 2nd TAB is li.daddy itself detected, thus showing the sub-menu.

Bottom line appears to be that $(document.activeElement) is just not correct because it gives the previous keypress and not the current one.

Again, this is also what my opening quote said about keypress events.

I need the current keypress, not the previous one.

I just found this quote:

" A key’s default action is performed during the keydown event, so, naturally, by the time keyup propagates, the Tab key has changed the focus to the next field."

So … maybe, I should look at on('keyup' rather than on('keydown' … just thinking out loud.

I’ve found that the keydown event (along with keypress) gives the previous element, and the keyup event gives the current element.

That might help with the activeElement issue.

And here’s some further details from quirksmode about keydown, keypress, and keyup that might be useful too.

https://www.quirksmode.org/dom/events/keys.html

Paul, I love your improvement of my windy version.

Here’s my “key up” version

No cycling yet + shift-TAB needs work

lovesongforever.com/testmenubar

1 Like