DEV Community

Masui Masanori
Masui Masanori

Posted on

[TypeScript] Select HTMLElements by tabindex

Intro

This time, I will try selecting HTMLElements by tabindex.
To do this, I use "querySelector" or "querySelectorAll" because the Document interface doesn't have a dedicated method to select elements by tabindex.
And to select the next element, I will use "ArrowUp" key and "ArrowDown" key.

Sample code

selectElem.html

<!DOCTYPE html>
<html>
    <head>
        <title>Select Element Sample</title>
        <meta charset="utf-8">
    </head>
    <body>
        <select tabindex="1">
            <option>sample</option>
        </select>
        <input type="text" tabindex="2">
        <div tabindex="3">Sample Label</div>
        <div tabindex="5">Sample Label2</div>
        <button>sample</button>
        <script src="./js/selectElem.page.js"></script>
        <script>Page.init();</script>
    </body>
</html>
Enter fullscreen mode Exit fullscreen mode

selectElem.page.ts

export function init() {
    document.body.onkeydown = (ev) => {
        switch(ev.key) {
            case "ArrowUp":
                getPreviousElement(1, 5).focus();
                break;
            case "ArrowDown":
                getNextElement(1, 5).focus();
                break;
        }
    };    
}
function getCurrent(): number {
    return (document.activeElement as HTMLElement).tabIndex;
}
function getPreviousElement(minIndex: number, maxIndex: number): HTMLElement {
    const maxTryCount = maxIndex - minIndex;
    let tryCount = 0;
    let previousIndex = getCurrent() - 1;
    while(true) {
        previousIndex = getPreviousTabIndex(previousIndex, minIndex, maxIndex);        
        const target = document.querySelector(`[tabindex='${previousIndex}']`);
        if(target != null) {
            return target as HTMLElement;
        }
        tryCount += 1;
        if(tryCount > maxTryCount) {
            throw Error("Previous Element was not found");
        }
        previousIndex -= 1;
    }
}
function getNextElement(minIndex: number, maxIndex: number): HTMLElement {
    const maxTryCount = maxIndex - minIndex;
    let tryCount = 0;
    let nextIndex = getCurrent() + 1;

    while(true) {
        nextIndex = getNextTabIndex(nextIndex, minIndex, maxIndex);
        const target = document.querySelector(`[tabindex='${nextIndex}']`);
        if(target != null) {
            return target as HTMLElement;
        }
        tryCount += 1;
        if(tryCount > maxTryCount) {
            throw Error("Next Element was not found");
        }
        nextIndex += 1;
    }
}
function getPreviousTabIndex(previousIndex: number, minIndex: number, maxIndex: number): number {
    if(previousIndex < minIndex) {
        return maxIndex;
    }
    if(previousIndex > maxIndex) {
        return maxIndex;
    }
    return previousIndex;
}
function getNextTabIndex(nextIndex: number, minIndex: number, maxIndex: number): number {
    if(nextIndex < minIndex) {
        return minIndex;
    }
    if(nextIndex > maxIndex) {
        return minIndex;
    }
    return nextIndex;
}
Enter fullscreen mode Exit fullscreen mode

Resources

Top comments (0)