javascript - Campo de texto de autofoco de Mobile Safari
focus mobile-safari (6)
En Mobile Safari, no puedo centrarme en un campo de texto después de establecer un período de retraso. Adjunto un código de ejemplo que muestra el problema. Si, al hacer clic en el botón, desencadena .focus (), todo funciona como se esperaba. Si se centra en una devolución de llamada, como la función setTimeout, entonces SOLO falla en el safari móvil. En todos los demás navegadores, hay un retraso, luego ocurre el enfoque.
De manera confusa, el evento "focusin" se desencadena, incluso en safari móvil. Esto (y ~ comentarios similares en SO) me hacen pensar que es un error de safari móvil. Cualquier orientación será aceptada.
Probé en el emulador y en el iPhone 3GS / 4 iOS4.
Ejemplo de HTML:
<!DOCTYPE html>
<html lang=''en''>
<head>
<title>Autofocus tests</title>
<meta content=''width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0'' name=''viewport''>
<meta content=''yes'' name=''apple-mobile-web-app-capable''>
</head>
<body>
<h1>
Show keyboard without user focus and select text:
</h1>
<p>
<button id=''focus-test-button''>
Should focus on input when you click me after .5 second
</button>
<input id=''focus-test-input'' type=''number'' value=''20''>
</p>
<script type="text/javascript">
//<![CDATA[
var button = document.getElementById(''focus-test-button'');
var input = document.getElementById(''focus-test-input'');
input.addEventListener(''focusin'', function(event) {
console.log(''focus'');
console.log(event);
});
button.addEventListener(''click'', function() {
// *** If triggered immediately - functionality occurs as expected
// input.focus();
// *** If called by callback - triggers the focusin event, but does not bring up keyboard or cursor
var t = setTimeout("input.focus();",500);
});
//]]>
</script>
</body>
</html>
~ Similar ~ SO preguntas:
Agregando a Matt respuesta. Al menos en Safari en iOS 5.1, este problema está solucionado. Su FastClick
funciona, es decir, al sintetizar un evento de clic no fallará el enfoque. Sin embargo, esto no ayuda a las personas que quieren que su código single focus()
funcione en todas las versiones de iOS, suspiro.
Creo que esta es una característica de Safari móvil en lugar de un error. En nuestro trabajo sobre FastClick , mis colegas y yo descubrimos que iOS solo permitirá desencadenar el enfoque en otros elementos, desde dentro de una función, si la primera función en la pila de llamadas fue desencadenada por un evento no programático. En su caso, la llamada a setTimeout
inicia una nueva pila de llamadas, y el mecanismo de seguridad se setTimeout
para evitar que se centre en la entrada.
Recuerde que en la configuración de iOS, enfocarse en un elemento de entrada hace que aparezca el teclado, por lo que todas las páginas web que se centren en un elemento de entrada en la carga de la página, como Google, serían extremadamente molestas de usar en iOS. Supongo que Apple decidió que tenían que hacer algo para evitar esto. Entonces no estoy de acuerdo con @DA: esta es una característica, no un error.
No hay una solución conocida para esto, por lo que tendrá que abandonar la idea de utilizar un retraso.
Actualización de agosto de 2012:
A partir de iOS 5, los controladores activados por eventos de clic sintetizados pueden activar el foco en los elementos de entrada. Pruebe el ejemplo actualizado de enfoque de entrada de FastClick .
Parece que focus () solo funciona, si ha agregado el sitio a la pantalla de inicio y ha abierto el sitio con este enlace.
Pude hacer que el trabajo .focus () se adjunte a dos eventos separados en el mapa de eventos, pero es un poco hacky.
Después de agregar FastClick.js, esto es lo que sucede en iOS: .focus () solo funciona cuando está activado por una función que está conectada a un evento. PERO el foco también es un evento en el mapa de eventos de un safari móvil que se llama cuando se utiliza .focus () de jQuery. Por lo tanto, puede ser redundante y adjuntar otro .focus () en el evento de enfoque del objeto para asegurarse de que se activa. Esto funciona especialmente bien cuando está creando una entrada en el DOM. Me gusta programar para MeteorJS últimamente, así es como se ve la solución allí:
Template.templateName.events({
"click button":function(){
Session.set("makeButtonVisible",true);
$("input.created").focus();
},
"focus input.created":function(){
$("input.created").focus();
}
});
Espero que esto sea útil para alguien, me tomó como dos horas resolver esto.
EDITAR: Bueno, para MeteorJS en particular, no puedes usar la función Template.templateName.rendered porque el .focus () debe invocarse desde un evento. PERO por alguna razón, cuando agrega una entrada a través de jQuery puede enfocarse en el evento. Supongo que ese es el camino a seguir. Esto es lo que terminé haciendo:
Template.templateName.events({
"click button":function(){
$("body").append("<input class=''created'' type=''tel''>");
$("input.created").focus();
}
});
Pude subir el teclado enviando un evento de clic solo cuando el evento original provenía de la interacción del usuario, no de setTimeout. Creo que el resultado es que puedes subir el teclado de un evento de touchend, pero aún no de un tiempo de espera.
Usted respondió a sí mismo. Solo necesitas activar si usas Jquery. Cambiar el foco () en el gatillo ("foco"); en cualquier parte de tu código
$ ("# searchField"). trigger ("foco");