简体   繁体   中英

How can i move from one element to another when pressing a button

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>

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 JavaScript code 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 index 0 , second button will be at the index 1 and so on).
  • initially, all the button do not have the data-is-focused attribute which will be considered as if that attribute is set to 0 .
  • 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-focused attribute set to 1 .
    • if no button is focused then we manually set the index to 0 so 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 0 to the index of the button to be focused.

To illustrate, here's a live demo, that handles returning back to the first button once we reach the last one (as described above):

Update: allow using shift key to move backwards

 const btns = Array.from(document.querySelectorAll("button")), /** * guess the index of the buitton to be focused based on the index of the currently focused button and whether we want to walk forwards or backwards. */ guessNextButtonIndex = (focusedBtnIndex, inReverseOrder) => { return inReverseOrder? (focusedBtnIndex <= 0? btns.length - 1: focusedBtnIndex - 1): (focusedBtnIndex === -1 || focusedBtnIndex === btns.length - 1? 0: focusedBtnIndex + 1); }; document.body.addEventListener("keydown", e => { // because we accept shift key, when you press shift + "b" the output will be "B" (uppercased) so we need to transform that to lower case. if (e.key.toLowerCase() === "b") { // 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), btnToFocus = btns[guessNextButtonIndex(idx, e.shiftKey)]; // 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>

Your code is half-way there, You need to select all the buttons by using querySelectorAll, because using querySelector it will only return the first matching element. and then keep track of which button you are focusing each time you call the function: So with the edits it would look like this:

let buttons = document.querySelectorAll('button');
let currentButton = 0;

document.body.addEventListener('keypress', e => {
  if (e.key == 'b') {
    e.preventDefault();
    currentButton++; // move to the next button in the list
    if (currentButton >= buttons.length) {
      currentButton = 0; // loop back to the first button if we reach the end of the list
    }
    buttons[currentButton].focus();
  }
});

 const boxes = document.querySelectorAll('button'); var boxesLength = boxes.length; for (var i = 0; i < boxesLength; i++) { boxes[i].addEventListener('click', function (i) { var findnextbtn; if ((boxesLength - 1) == i) { removeStyle(); findnextbtn = boxes[0]; } else { removeStyle(); findnextbtn = boxes[i + 1]; } findnextbtn.setAttribute('style', 'background-color: yellow;'); }.bind(null, i)); } function removeStyle() { boxes.forEach(box => { box.setAttribute('style', 'background-color: none;'); }); }
 <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>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM