WebHotkeys

Hit F1 for the help dialog, F2 to badge every element having a hotkey.

Programmatic

Hit f or 1 - both are grabbed by the snippet below. The letter goes by key (what the layout produces), the digit by code (the physical key, so it fires on any layout). F1 lists every hotkey on this page.

const wh = window.webHotkeys  // the <script data-register> tag made this one

wh.grab("f", "The letter f alone", () => alert("The letter f hit"))
wh.grab("Digit1", "Digit 1, whatever the keyboard layout", () => alert("Digit1 hit"))

Declarative

No JavaScript at all - the data-hotkey attribute is enough. Hit Ctrl+j to click the button, Alt+n to focus the note, Alt+c to tick the checkbox. A whole data-hotkey-group shows up as one section in the F1 dialog.

What the element does is chosen by its type - a text field is focused, a button, a checkbox and a radio clicked, a <details> toggled; data-hotkey-action overrides that (click, focus, toggle, none). Hence Alt+1/Alt+2 pick a radio (and focus it, so the arrows go on from there) while Alt+c only flips the checkbox, and Alt+d opens the details although clicking it would do nothing.

<button onclick="alert('Clicked the button')" data-hotkey="Ctrl+j">button</button>

<span data-hotkey-group="Form">
    <input data-hotkey="Alt+n" title="Focus the note" placeholder="a note">
    <input type="checkbox" data-hotkey="Alt+c" title="Flip me">
    <input type="radio" name="size" value="s" data-hotkey="Alt+1" title="Small">
    <input type="radio" name="size" value="m" data-hotkey="Alt+2" title="Medium">
</span>

<details data-hotkey="Alt+d" title="Open me">
    <summary>a details, toggled by default</summary>
</details>
a details, toggled by default It sits outside the Form group, so F1 lists it among the ungrouped hotkeys.

Sequences

Hit g then i. The g alone is not grabbed at all - the key is swallowed and waits for the rest of the sequence. Tap Shift twice for a double tap.

The list helper

Arrows, Home/End, or type the first letters of a track.

The grid helper

Click a cell first - that both scopes the arrows to this table (not the whole page) and marks where to start from. Then / keep the column, / move within the row.

wh.grid("#grid tr", "td", { scope: "#grid", wrap: true })
A1B1C1
A2B2C2
A3B3C3

Arrow keys inside a text field

Type into the box, then hit / to move through the suggestions below it - normally an arrow key inside a text field only moves the caret, {inInput: true} unlocks it.

Remapping

Alt+r shows an alert. Hit F1 and click any combination there to press your own – a whole sequence works too (type g i and pause). The layout is kept in the localStorage, puts the default back.

Or record it yourself:

Currently active shortcuts