javascriptdom

finding next/previous element with tabindex=0?


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.


Solution

  • 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