Reputation: 1640
When I call input.focus()
from the touch event listener it focuses the input for a few ms, but focus is given immediately back to the touched element. I tested that also on my phone (real touch device) and the behavior is the same. I tried to google some documentation about that, but didn't find anything useful.
The only current workaround I use is setTimeout(() => input.focus(), 500)
, which is pretty sloppy way to do this. Any ideas?
https://codepen.io/xpuu/pen/BXpBZY
document.addEventListener("DOMContentLoaded", function() {
let input = document.getElementById("test");
let events = {
click(e) {
console.log("click");
input.focus();
},
touchstart(e) {
console.log("touchstart");
input.focus();
},
touchend(e) {
console.log("touchend");
input.focus();
},
touchprevent(e) {
console.log("touchprevent");
e.preventDefault();
input.focus();
},
touchtimeout(e) {
console.log("touchtimeout");
setTimeout(() => input.focus(), 500);
}
};
let buttons = document.getElementById("buttons");
let validEvents = ["click", "touchstart", "touchend"];
Object.keys(events).forEach(key => {
let handler = key;
let btn = document.createElement("button");
btn.innerText = key;
if (!validEvents.includes(handler)) {
handler = "touchstart";
}
//console.log(handler, key);
btn.addEventListener(handler, events[key]);
buttons.appendChild(btn);
});
});
input {
padding: 3px;
}
<p>Enable devtools / responsive mode and touch emulation for this to work</p>
<input id="test" value="focus me please">
<p id="buttons"></p>
Upvotes: 2
Views: 1324
Reputation: 1640
As Chris mentioned, you have to run e.preventDefault()
before focusing the input. Also it's important to disable passive
handler in the addEventListener
options.
let touchprevent = e => {
console.log("touchprevent");
e.preventDefault();
input.focus();
}
input.addEventListener('touchstart', touchprevent, { passive: false });
Upvotes: 2