最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Why the next textbox was fired keyup event after I press Enter on the button and focus on next textbox - Stack Over

programmeradmin0浏览0评论

I have a list of textbox and button:

<p>Please type Enter to move to the next element</p>
<input id="item-0" class="item" type="text" index="0" /><br/>
<button id="item-1" class="btn-item" type="button" index="1">Confirm</button><br/>
<input id="item-2" class="item" type="text" index="2" /><br/>
<input id="item-3" class="item" type="text" index="3" /><br/>
<input id="item-4" class="item" type="text" index="4" />

My purpose: when I hit Enter on a textbox or button, the next element will be focus on. But with the button, when I hit Enter it will move to the next element and that element continues to fire the keyup event (Enter) and move to the next one.

const selects = document.querySelectorAll('.item');
 selects.forEach(el => el.addEventListener('keyup', e => { 
    if (e.key === 'Enter' || e.keyCode === 13) {
        let idx = parseInt(e.currentTarget.getAttribute("index"));
    focusToTheNextControl(idx);
    }
}));
document.querySelector('.btn-item').addEventListener('click', e => { 
   let idx = parseInt(e.currentTarget.getAttribute("index"));
   focusToTheNextControl(idx);
});
function focusToTheNextControl(idx) {   
  document.querySelector("#item-" + (idx + 1)).focus();
}

const selects = document.querySelectorAll('.item');
selects.forEach(el => el.addEventListener('keyup', e => {
  if (e.key === 'Enter' || e.keyCode === 13) {
    let idx = parseInt(e.currentTarget.getAttribute("index"));
    focusToTheNextControl(idx);
  }
}));

document.querySelector('.btn-item').addEventListener('click', e => {
  let idx = parseInt(e.currentTarget.getAttribute("index"));
  focusToTheNextControl(idx);
});

function focusToTheNextControl(idx) {
  document.querySelector("#item-" + (idx + 1)).focus();
}
<p>Please type Enter to move to the next element</p>
<input id="item-0" class="item" type="text" index="0" /><br/>
<button id="item-1" class="btn-item" type="button" index="1">Confirm</button><br/>
<input id="item-2" class="item" type="text" index="2" /><br/>
<input id="item-3" class="item" type="text" index="3" /><br/>
<input id="item-4" class="item" type="text" index="4" />

I have a list of textbox and button:

<p>Please type Enter to move to the next element</p>
<input id="item-0" class="item" type="text" index="0" /><br/>
<button id="item-1" class="btn-item" type="button" index="1">Confirm</button><br/>
<input id="item-2" class="item" type="text" index="2" /><br/>
<input id="item-3" class="item" type="text" index="3" /><br/>
<input id="item-4" class="item" type="text" index="4" />

My purpose: when I hit Enter on a textbox or button, the next element will be focus on. But with the button, when I hit Enter it will move to the next element and that element continues to fire the keyup event (Enter) and move to the next one.

const selects = document.querySelectorAll('.item');
 selects.forEach(el => el.addEventListener('keyup', e => { 
    if (e.key === 'Enter' || e.keyCode === 13) {
        let idx = parseInt(e.currentTarget.getAttribute("index"));
    focusToTheNextControl(idx);
    }
}));
document.querySelector('.btn-item').addEventListener('click', e => { 
   let idx = parseInt(e.currentTarget.getAttribute("index"));
   focusToTheNextControl(idx);
});
function focusToTheNextControl(idx) {   
  document.querySelector("#item-" + (idx + 1)).focus();
}

const selects = document.querySelectorAll('.item');
selects.forEach(el => el.addEventListener('keyup', e => {
  if (e.key === 'Enter' || e.keyCode === 13) {
    let idx = parseInt(e.currentTarget.getAttribute("index"));
    focusToTheNextControl(idx);
  }
}));

document.querySelector('.btn-item').addEventListener('click', e => {
  let idx = parseInt(e.currentTarget.getAttribute("index"));
  focusToTheNextControl(idx);
});

function focusToTheNextControl(idx) {
  document.querySelector("#item-" + (idx + 1)).focus();
}
<p>Please type Enter to move to the next element</p>
<input id="item-0" class="item" type="text" index="0" /><br/>
<button id="item-1" class="btn-item" type="button" index="1">Confirm</button><br/>
<input id="item-2" class="item" type="text" index="2" /><br/>
<input id="item-3" class="item" type="text" index="3" /><br/>
<input id="item-4" class="item" type="text" index="4" />

I try to delay focus on the next element by using setTimeout in 1sec and it stops. I have no ideal how it works and the right way to stop it. Thanks for you help.

Share Improve this question edited Nov 20, 2024 at 0:05 mykaf 1,4121 gold badge11 silver badges14 bronze badges asked Nov 19, 2024 at 16:02 Qudu TaQudu Ta 32 bronze badges 3
  • "Enter" on your button also acts as a click, so it's calling focusToTheNextControl() twice. Perhaps you should exclude the button from your keyup listener. – mykaf Commented Nov 19, 2024 at 17:27
  • By the way, there is no jquery here. – mykaf Commented Nov 19, 2024 at 17:27
  • 1 Just fyi, changing the effect of pressing ENTER in a UI is rarely a good UX choice. – Scott Marcus Commented Nov 19, 2024 at 17:32
Add a comment  | 

1 Answer 1

Reset to default 0

This happens when you press enter after you focus the button, which triggers the click event along with the event handler for the next focused input. One way to prevent this is to use the keydown event with event.preventDefault():

const selects = document.querySelectorAll('.item');

selects.forEach(el => el.addEventListener('keydown', e => {
  if (e.key === 'Enter' || e.keyCode === 13) {
    let idx = parseInt(e.target.getAttribute("index"));
    focusToTheNextControl(idx);
    e.preventDefault();
  }
}));

document.querySelector('.btn-item').addEventListener('click', e => {
  let idx = parseInt(e.target.getAttribute("index"));
  focusToTheNextControl(idx);
});

function focusToTheNextControl(idx) {
  document.querySelector("#item-" + (idx + 1)).focus();
}
<p>Please type Enter to move to the next element</p>
<input id="item-0" class="item" type="text" index="0" /><br/>
<button id="item-1" class="btn-item" type="button" index="1">Confirm</button><br/>
<input id="item-2" class="item" type="text" index="2" /><br/>
<input id="item-3" class="item" type="text" index="3" /><br/>
<input id="item-4" class="item" type="text" index="4" />

If you want to, you can also skip the Confirm button entirely by only changing to keydown event without event.preventDefault()

const selects = document.querySelectorAll('.item');

selects.forEach(el => el.addEventListener('keydown', e => {
  if (e.key === 'Enter' || e.keyCode === 13) {
    let idx = parseInt(e.target.getAttribute("index"));
    focusToTheNextControl(idx);
  }
}));

document.querySelector('.btn-item').addEventListener('click', e => {
  let idx = parseInt(e.target.getAttribute("index"));
  focusToTheNextControl(idx);
});

function focusToTheNextControl(idx) {
  document.querySelector("#item-" + (idx + 1)).focus();
}
<p>Please type Enter to move to the next element</p>
<input id="item-0" class="item" type="text" index="0" /><br/>
<button id="item-1" class="btn-item" type="button" index="1">Confirm</button><br/>
<input id="item-2" class="item" type="text" index="2" /><br/>
<input id="item-3" class="item" type="text" index="3" /><br/>
<input id="item-4" class="item" type="text" index="4" />

发布评论

评论列表(0)

  1. 暂无评论