focus() not working within setTimeout on iOS
jQuery's focus() method is does not appear to work when used from开发者_StackOverflow within a setTimeout in iOS.
So,
setTimeout( function () {
// Appears to have no effect in iOS, fine in Chrome/Safari/Firefox/IE
$('.search').focus();
}, 500);
But on it's own,
// works fine.
$('.search').focus();
See the following example:
http://jsfiddle.net/nwe44/ypjkH/1/
If the focus() call is made outside the setTimeout it works, inside it doesn't. This is doubly curious as other methods do work. For example, in my jsFiddle I'm able to change the border color, just not focus it. Any ideas?
Check fiddle i have updated at http://jsfiddle.net/ypjkH/7/
$('#selector').click( function (e) {
e.preventDefault();
setTimeout( doFocus
, 3000);
});
function doFocus() {
$('.search').focus().css('border', '1px solid red');
}
For my app it works, if you just put the x.focus() into a(nother) separate function and call it from within the setTimeout
Safari's approach to focus
is that it will only work within the same event loop. Therefore, if it's inside a Promise
or a timeout, it will not open the keyboard.
By today, it's impossible to open the keyboard after the timeout.
The only workaround you have is to use this hack:
/**
* iOS keyboard can only be opened by user interaction + focus event.
* There are situations in which we need to open keyboard programmatically
* before other elements are rendered, like when opening an overlay. this function can be used
* to open the keyboard before the overlay is rendered, and once the overlay is
* rendered, it's needed to focus to the desired input element, and the keyboard
* will stay open.
*
* This function needs to be called from native events attached to HTML elements. It will
* not work if called from a "passive" event, or after any event not coming from
* user interaction (onLoad, onFocus, etc).
*
* It's recommended to use it on MouseEvents or TouchEvents.
*/
export function openIosKeyboard() {
const input = document.createElement("input");
input.setAttribute("type", "text");
input.setAttribute("style", "position: fixed; top: -100px; left: -100px;");
document.body.appendChild(input);
input.focus();
// it's safe to remove the fake input after a 30s timeout
setTimeout(() => {
document.body.removeChild(input);
}, 30 * 1000);
}
精彩评论