'focus() function doesn't work in Firefox
I have some JS that shows a search modal and gives the search focus. It looks like this:
function searchOpen(event) {
event.preventDefault();
searchOverlay.classList.add("show");
searchOverlayInput.focus();
}
Seems to work OK in chrome and safari, but in FireFox the search does not focus.
I found:
Javascript focus not working in firefox
javascript focus() not working on Firefox and IE?
Both answers suggest 2 things
- User specific setting
- do a
setTimeout()
There are no user specific settings on my iMac that would prevent this from happening. As for suggestion #2 I tried:
function searchOpen(event) {
event.preventDefault();
searchOverlay.classList.add("show");
setTimeout(function(){searchOverlayInput.focus();}, 1);
}
It still doesn't work.
Any ideas?
Solution 1:[1]
I run code sort of like this to see if an element is available to focus. Basically check to see if it is visible, if not, than check again, until it is able to be focused.
function focusWhenVisible (elem) {
var cnt = 0;
var check = function () {
if (elem.offsetHeight) { //reports zero when hidden
elem.focus()
} else if (cnt++ < 1000) { // only check for a certain amount of iterations
setTimeout(check, 1);
}
}
check()
}
document.querySelector("#b1").addEventListener("click", function () {
var inp = document.querySelector("#in1");
focusWhenVisible(inp)
inp.removeAttribute("hidden");
});
document.querySelector("#b2").addEventListener("click", function () {
var inp = document.querySelector("#in2");
focusWhenVisible(inp)
window.setTimeout(()=>{inp.removeAttribute("hidden");},500)
});
<input type="input" id="in1" hidden />
<button type="button" id="b1">Click</button>
<input type="input" id="in2" hidden />
<button type="button" id="b2">Click w/ Delay</button>
Solution 2:[2]
Ran into this problem today too. The issue is that while Firefox focuses the component, it does not show the soft keyboard unless the event has been triggered from a click
event. Notably it does not work from a pointerdown
event for me, I did not try touchstart
.
Use your first code snippet, and see if it behaves as expected from a button click or such.
Wrapping the call to focus() in a setTimeout
is a no go, since it will lose the dynamic security context and fail.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | epascarello |
Solution 2 | mseddon |