Is there a way to find the next/previous (in document order) element with tabindex="0"
?
The closest I've gotten is:
case 'Tab':
let item = node.closest('.listbox').nextElementSibling
do {
const focusable = item.querySelector('[tabindex="0"]')
if (focusable) {
focusable.focus()
break;
}
item = item.nextElementSibling
if (item == null) break;
} while (!item.querySelector('[tabindex="0"]'))
break;
but this stops at the parent level.
querySelector
or similar functions already return the items in DOM traversal order. Instead of walking over them at each iteration, you can create a list of items once and return an object that increments/decrements over the selected ones:
const Items = Array.from(document.querySelectorAll('[tabindex="0"]'));
const clamp = (nr) => Math.max(0, Math.min(Items.length - 1, nr));
function iterate (item) {
let currIdx = Items.indexOf(item?.querySelector('[tabindex="0"]'));
return {
current: () => Items[currIdx]
next: () => { currIdx = clamp(currIdx + 1); return Items[currIdx]},
previous: () => { currIdx = clamp(currIdx - 1); return Items[currIdx]}
}
}
use MutationObserver
or similar mechanism to refresh the Items
if document content changes.
PS: I might have syntax errors, if you post an example I will run it on that