Home > OS >  Element.focus() doesn't work when called within a function handler for addEventListener()
Element.focus() doesn't work when called within a function handler for addEventListener()

Time:05-28

Here is my code. For some reason, this code does not give focus to the textbox with the id "dude" even though the paragraph tag with id "answer" does get the key code of the button that I clicked. It is like the line with the focus() command gets completely ignored.

document.getElementById("thing").addEventListener("keypress", function() {
  myFunction(event);
});

function myFunction(event) {
  document.getElementById("answer").innerHTML = event.keyCode;
  document.getElementById("dude").focus();
}
<!DOCTYPE html>
<html>

<body>

  <input type="text" id="thing">
  <input type="text" id="dude">
  <p id="answer"></p>

</body>

</html>

However, if I were to make a slight modification and put the line with the focus() outside of the addEventListener(), then the focus() would work. For example, the following code works:

document.getElementById("dude").focus();
document.getElementById("thing").addEventListener("keypress", function() {
  myFunction(event);
});

function myFunction(event) {
  document.getElementById("answer").innerHTML = event.keyCode;
}
<!DOCTYPE html>
<html>

<body>

  <input type="text" id="thing">
  <input type="text" id="dude">
  <p id="answer"></p>

</body>

</html>

The above code would actually start by giving the "dude" textbox focus.

Is there any reason for this and anything that I can do about this?

CodePudding user response:

The keypress event handler fires too early - the user hasn't finished pressing the key down and entering in the value at that point, so the focus reverts to the initial input field. See how if you change the focus after a setTimeout it'll work:

document.getElementById("thing").addEventListener("keypress", function() {
    myFunction(event);
  });

  function myFunction(event) {
    document.getElementById("answer").innerHTML = event.keyCode;
    setTimeout(() => document.getElementById("dude").focus());
  }
<input type="text" id="thing">
<input type="text" id="dude">
<p id="answer"></p>

Or watch for the keyup event instead:

document.getElementById("thing").addEventListener("keyup", function() {
  myFunction(event);
});

function myFunction(event) {
  document.getElementById("answer").innerHTML = event.keyCode;
  document.getElementById("dude").focus();
}
<input type="text" id="thing">
<input type="text" id="dude">
<p id="answer"></p>

For example, the following code works:

Not exactly, because with that code, you're focusing the dude input on pageload, rather than when the thing input has stuff typed into it.

You also should avoid using keypress in modern code, it's deprecated:

This feature is no longer recommended. Though some browsers might still support it, it may have already been removed from the relevant web standards, may be in the process of being dropped, or may only be kept for compatibility purposes. Avoid using it, and update existing code if possible; see the compatibility table at the bottom of this page to guide your decision. Be aware that this feature may cease to work at any time.

Since this event has been deprecated, you should look to use beforeinput or keydown instead.

keyCode is too, technically, but the replacement for it - .code - isn't compatible everywhere.

CodePudding user response:

Use the keyup event instead of keypress, because the default action of the keypress event sets the focus back to that input element.

document.getElementById("thing").addEventListener("keyup", function() {
  myFunction(event);
});

function myFunction(event) {
  document.getElementById("answer").innerHTML = event.keyCode;
  document.getElementById("dude").focus();
}
<!DOCTYPE html>
<html>

<body>

  <input type="text" id="thing">
  <input type="text" id="dude">
  <p id="answer"></p>

</body>

</html>

CodePudding user response:

It seems like you are trying to shift focus from input "thing" to input "dude" after you complete a "keypress" or "keyup" on input "thing".

I don't understand the use case for this. But, IMO if you are trying to change the focus state after you input a value, I would recommend placing an event listener on the "change" event. You could simply press your "TAB" key on your keyboard after you are done inputting data into input "thing" and focus will be shifted to the input "dude" and the function will execute. Both achieved!

document.getElementById("thing").addEventListener("change", function() {
  myFunction(event);
});

  • Related