$ .focus () no funciona

155

El último ejemplo de losfocus() estados de documentación de jQuery

$('#id').focus()

debe hacer la entrada enfocada (activa). Parece que no puedo hacer que esto funcione.

Incluso en la consola de este sitio, lo intento para el cuadro de búsqueda

$('input[name="q"]').focus()

Y no consigo nada. ¿Algunas ideas?

Sam Selikoff
fuente
2
¿Nos puede mostrar su código?
Adil
Tendremos que saber más, porque funciona bien para mí: jsfiddle.net/G7hwR/1 simplemente haga clic en cualquier parte del panel derecho y se enfoca ...
Rob G
Sin embargo, ¿no debería funcionar el enfoque en esta página? ¿El fragmento que proporcioné?
Sam Selikoff el
Depende de lo que contenga; si no está dentro de nada, es probable que se ejecute antes de que la página se muestre ...
Rob G
Para aquellos que vienen de búsqueda: las herramientas de desarrollo integradas en el navegador pueden interferir con la focus()funcionalidad. Más información
aexl

Respuestas:

392

En realidad, el ejemplo que diste para enfocarte en este sitio funciona bien, siempre y cuando no estés enfocado en la consola. La razón por la que no funciona es simplemente porque no está robando el foco de la consola de desarrollo. Si ejecuta el siguiente código en su consola y luego hace clic rápidamente en la ventana de su navegador, verá que enfoca el cuadro de búsqueda:

setTimeout(function() { $('input[name="q"]').focus() }, 3000);

En cuanto al otro, lo único que me ha causado problemas en el pasado es el orden de los eventos. No puede llamar a focus () en un elemento que no se ha adjuntado al DOM. ¿El elemento que está tratando de enfocar ya se ha adjuntado al DOM?

Justin Warkentin
fuente
1
¡Excelente! ¿Eso ayudó con tus dos problemas? Si es así, ¿podría marcarlo como la respuesta correcta? Lo agradecería mucho: D
Justin Warkentin
44
no use herramientas de desarrollador cuando solo use $ ('input [name = "q"]'). focus (); o no funcione
Amitābha
12
Wow, había estado luchando de vez en cuando con esto durante meses, solo vi que esto era causado por la apertura de la consola del desarrollador. El mío siempre lo es. ¡Gracias!
Alex Turpin
20
+1 para "No se puede llamar a focus () en un elemento que no se ha adjuntado al DOM". Además, parece que no se puede llamar a elementos ocultos.
tandrewnichols
1
El uso setTimeoutpara resolver problemas de orden de operaciones hace que sea un gran dolor mantener la patología. Si aparece un error, es realmente difícil de depurar. Donde sea que esté insertando el elemento en el DOM, debería llamar .focus()allí.
Kevin Beal
55

Encontró una solución en otra parte de la red ...

$('#id').focus();

no funcionó.

$('#id').get(0).focus();

funcionó

Cymro
fuente
44
Voté esta solución simplemente porque funcionó para mí cuando la solución más popular en esta página no lo hizo. ;-)
chriv
La segunda opción parece estar tomando el elemento dom y usando la versión regular de javascript en lugar de la versión jquery.
danielson317
77
¿Podría ser que tiene varios elementos con la identificación "id" en su página? El DOM no se romperá en este caso, pero tampoco puede asignar foco a múltiples elementos
DerpyNerd
Descubrí que tenía que hacer esto con un window.setTimeout con un retraso de 0, y luego todo está bien. Gracias. Todo lo demás que probé falló en un modo de arranque.
Wade Hatler
23

Algunas de las respuestas aquí sugieren usar setTimeoutpara retrasar el proceso de enfocarse en el elemento objetivo. Uno de ellos menciona que el objetivo está dentro de un diálogo modal. No puedo comentar más sobre la corrección de la setTimeoutsolución sin conocer los detalles específicos de dónde se utilizó. Sin embargo, pensé que debería proporcionar una respuesta aquí para ayudar a las personas que se encuentran con este hilo tal como lo hice yo

El simple hecho del asunto es que no puede enfocarse en un elemento que aún no es visible . Si se encuentra con este problema, asegúrese de que el objetivo sea realmente visible cuando se haga el intento de enfocarlo. En mi propio caso estaba haciendo algo en este sentido

$('#elementid').animate({left:0,duration:'slow'});
$('#elementid').focus();

Esto no funcionó. Sólo me di cuenta de lo que estaba pasando cuando ejecuté $ ( '# elementID'). Enfoque () `de la consola, que hizo el trabajo. La diferencia: en mi código sobre el objetivo no hay certeza de que el objetivo sea visible ya que la animación puede no estar completa . Y ahí yace la pista

$('#elementid').animate({left:0,duration:'slow',complete:focusFunction});

function focusFunction(){$('#elementid').focus();}

Funciona tal como se esperaba. Yo también había puesto inicialmente una setTimeoutsolución y también funcionó. Sin embargo, un tiempo de espera elegido arbitrariamente romperá la solución tarde o temprano, dependiendo de la lentitud del proceso del dispositivo host para garantizar que el elemento objetivo sea visible.

DroidOS
fuente
La sugerencia relevante para mí fue "asegurarse de que el objetivo sea realmente visible". Esto se vuelve relevante cuando se trata de centrarse en elementos renderizados condicionalmente.
Charlie Carver
O cuando el elemento a enfocar tiene visibility:hidden, no se enfocará.
bakrall
`no puedes concentrarte en un elemento que aún no es visible` - Te amo. Simplemente agregando un tiempo de espera de 100 ms, podría activar el enfoque en mi cuadro de búsqueda oculto. ¡Gracias!
LuBre
Cuidado con los tiempos de espera. Lo que funciona en su máquina de desarrollo puede no funcionar en otra.
DroidOS
15

si usa bootstrap + modal, esto funcionó para mí:

  $(myModal).modal('toggle');
  $(myModal).on('shown.bs.modal', function() {
    $('#modalSearchBox').focus()
  });
Wolf359
fuente
8

En caso de que alguien más se encuentre con esta pregunta y tenga la misma situación que yo, estaba tratando de establecer el enfoque después de hacer clic en otro elemento, pero el enfoque no parecía funcionar. Resulta que solo necesitaba un e.preventDefault();- aquí hay un ejemplo:

$('#recipients ul li').mousedown(function(e) {
    // add recipient to list
    ...
    // focus back onto the input
    $('#message_recipient_input').focus();
    // prevent the focus from leaving
    e.preventDefault();
});

Esto ayudó a:

Si llama a HTMLElement.focus () desde un controlador de eventos de mousedown, debe llamar a event.preventDefault () para evitar que el foco salga de HTMLElement. Fuente: https://developer.mozilla.org/en/docs/Web/API/HTMLElement/focus

Ben
fuente
2
¡El único funciona! Trigger es un div emergente, haga clic para ocultar el div y poner algún valor en un cuadro de texto (no es necesario enfocarlo). Sin preventDefault, ese cuadro de texto siempre está enfocado sin importar qué -__-
rlatief
4

Me doy cuenta de que esto es viejo, pero lo encontré hoy. Ninguna de las respuestas funcionó para mí, lo que sí encontré que funcionó fue setTimeout. Quería que mi atención se centrara en la entrada archivada de un modal, usando el setTimeout trabajado. ¡Espero que esto ayude!

usuario3861385
fuente
¡Yo también! Y la duración del tiempo de espera realmente marcó la diferencia. Estúpido IE.
eaglei22
1
Pero no funciona en dispositivos móviles. Los navegadores móviles ignoran en la mayoría de los casos todo lo que está dentro de setTimeout
Kosmonaft el
1
Como regla general, usar setTimeoutes una mala solución. No puede garantizar el tiempo de ejecución en la máquina del usuario, por lo que las cosas que dependen del tiempo son extremadamente frágiles.
Nathan
3

Yo también tuve este problema. La solución que funcionó en mi caso fue usar la propiedad tabindex en el elemento HTML.

Estaba usando ng-repeatalgunos elementos li dentro de una lista y no pude enfocar la primera li usando .focus (), así que simplemente agregué el atributo tabindex a cada li durante el ciclo.

y ahora <li ng-repeat="user in users track by $index" tabindex="{{$index+1}}"></li>

Que +1 era índice comienza desde 0. También asegúrese de que el elemento esté presente en DOM antes de llamar a la función .focus ()

Espero que esto ayude.

Kumar Shubham
fuente
2

Para aquellos con el problema de no funcionar porque usaste "$ (element) .show ()". Lo resolví de la siguiente manera:

 var textbox = $("#otherOption");
 textbox.show("fast", function () {
    textbox[0].focus();
  });

Por lo tanto, no necesita un temporizador, se ejecutará después de que se complete el método show.

Rolando Retana
fuente
Esto se aplica a cualquier otra transición: slideDown(), fadeIn(), etc.
Álvaro González
2

Agregue un retraso antes del foco (). 200 ms es suficiente

function focusAndCursor(selector){
  var input = $(selector);
  setTimeout(function() {
    // this focus on last character if input isn't empty
    tmp = input.val(); input.focus().val("").blur().focus().val(tmp);
  }, 200);
}
Abel
fuente
0

Tuve este problema nuevamente en este momento, y lo creas o no, todo lo que tuve que hacer fue cerrar las herramientas del desarrollador. Aparentemente, la pestaña Consola tiene la prioridad de enfoque sobre el contenido de la página.

aexl
fuente
0

Asegúrese de que el elemento y sus padres sean visibles. No puedes usar el foco en elementos ocultos

marioviales
fuente
-1

Para mi caso, tuve que especificar un índice de pestaña ( -1si solo se puede enfocar a través de un script)

<div tabindex='-1'>
<!-- ... -->
</div>
Alexandre Daubricourt
fuente