Hi all I am a newby and I am trying to create a function that when I press a button for example the ‘b’ key focus will move from one button on the page to the next. I am able to set the focus on the first button of the page but when I press the ‘b’ key again focus stays on the first button.
let btn = document.querySelector("button");
document.body.addEventListener("keypress", (e) => {
if (e.key == "b") {
e.preventDefault();
document.querySelector("button").focus();
}
});
<button>Button 1</button><br>
<button>Button 2</button><br>
<button>Button 3</button><br>
<button>Button 4</button><br>
<button>Button 5</button><br>
>Solution :
A quick way to achieve that is by setting a data-* attribute, let’s call it data-is-focused to the currently focused button where the value will be 1 and then we set that to 0 once the button loses focus and based on that attribute, the data-is-focused attribute, we can easily tell which button is currently selected and we can easily move focus to the next one.
The idea is simple:
- we select all the buttons and cache them in the
JavaScriptcode so we can easily access them when needed. Each button will have an index based on its appearance in the document tree (first button will have the index0, second button will be at the index1and so on). - initially, all the button do not have the
data-is-focusedattribute which will be considered as if that attribute is set to0. - once
"b"is pressed we make some checks:- get the currently focused button by finding the index of the button that has the
data-is-focusedattribute set to1. - if no button is focused then we manually set the index to
0so we focus the first button. - Otherwise, if we find the currently focused button, we increment the index.
- if we reach the last button, the index equals the number of buttons – 1 (remember, indexes start from 0) then we simply set
0to the index of the button to be focused.
- get the currently focused button by finding the index of the button that has the
To illustrate, here’s a live demo, that handles returning back to the first button once we reach the last one (as described above):
const btns = Array.from(document.querySelectorAll("button"));
document.body.addEventListener("keypress", e => {
if (e.key === "b") {
e.preventDefault();
// get the index of the currently focused button based on the data-is-focused attribute. If no button is focused, -1 is returned.
const idx = btns.findIndex(btn => btn.dataset.isFocused == 1),
/**
* the button to be focused will be:
* - if "idx" equals -1 or we have reached the mlast button (idx equals the buttons number - 1), then the button to be focused will be at the index 0.
* - otherwiose, the button to be focused will be at the index "idx + 1"
*/
btnToFocus = btns[idx === -1 || idx === btns.length - 1 ? 0 : idx + 1];
// set the data-is-focused of the last focused button to "0"
idx !== -1 && (btns[idx].dataset.isFocused = 0);
// set the data-is-focused of the button to be focused to "1"
btnToFocus.dataset.isFocused = 1;
// focus the button to be focused
btnToFocus.focus();
}
});
<button>Button 1</button><br>
<button>Button 2</button><br>
<button>Button 3</button><br>
<button>Button 4</button><br>
<button>Button 5</button><br>