$ .focus () não está funcionando

155

O último exemplo da focus()documentação do jQuery indica

$('#id').focus()

deve tornar a entrada focada (ativa). Parece que não consigo fazer isso funcionar.

Mesmo no console deste site, estou tentando pela caixa de pesquisa

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

e eu não estou conseguindo nada. Alguma ideia?

Sam Selikoff
fonte
2
Você pode nos mostrar seu código?
711 Adil
Nós vamos ter que saber mais, porque ele funciona muito bem para mim: jsfiddle.net/G7hwR/1 basta clicar em qualquer lugar no painel direito e centra-se ...
Rob G
O foco nesta página não deveria funcionar? O trecho que eu forneci?
Sam Selikoff
Depende do que está contido; se não é dentro de qualquer coisa, é provável a ser executado antes de a página é processada mesmo ...
Rob G
Para quem vem da pesquisa: as ferramentas de desenvolvedor incorporadas do navegador podem interferir na focus()funcionalidade. Mais informações
aexl

Respostas:

392

Na verdade, o exemplo que você deu para se concentrar neste site funciona muito bem, desde que você não esteja focado no console. O motivo pelo qual não está funcionando é simplesmente porque não está roubando o foco do console de desenvolvimento. Se você executar o seguinte código no console e clicar rapidamente na janela do navegador, verá o foco na caixa de pesquisa:

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

Quanto ao seu outro, a única coisa que me deu problemas no passado é a ordem dos eventos. Você não pode chamar focus () em um elemento que não foi anexado ao DOM. O elemento que você está tentando focar já foi anexado ao DOM?

Justin Warkentin
fonte
1
Ótimo! Isso ajudou nos dois problemas? Em caso afirmativo, você poderia marcá-lo como a resposta correta? Eu seria muito apreciá-lo: D
Justin Warkentin
4
não use ferramentas para desenvolvedores quando apenas utilizar $ ( 'input [name = "q"]') foco ();. ou não trabalho
Amitābha
12
Uau, eu estava lutando com isso há meses, só vi que isso é causado pelo console do desenvolvedor estar aberto. O meu sempre é. Obrigado!
Alex Turpin #
20
+1 em "Você não pode chamar focus () em um elemento que não foi anexado ao DOM". Além disso, parece que você não pode chamá-lo de elementos ocultos.
precisa saber é o seguinte
1
Usar setTimeoutpara resolver problemas de ordem de operações torna uma enorme dor no patooty manter. Se um bug aparecer, é realmente difícil depurar. Onde quer que você esteja inserindo o elemento no DOM, ele deve chamar .focus()lá.
Kevin Beal
55

Encontrou uma solução em outro lugar na rede ...

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

não funcionou.

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

funcionou.

Cymro
fonte
4
Eu votei nessa solução apenas porque funcionou para mim quando a solução mais popular nesta página não funcionou. ;-)
chriv 21/01
A segunda opção parece pegar o elemento dom e usar a versão javascript regular em vez da versão jquery.
Danielson317
7
Será que você tem vários elementos com o ID "id" em sua página? O DOM não vai quebrar, neste caso, mas você não pode se concentrar atribuir a vários elementos, quer
DerpyNerd
Descobri que tinha que fazer isso com um window.setTimeout com um atraso de 0 e, então, está tudo bem. Obrigado. Todo o resto que tentei falhou em um modal de inicialização.
Wade Hatler #
23

Algumas das respostas aqui sugerem o uso setTimeoutpara atrasar o processo de foco no elemento de destino. Um deles menciona que o alvo está dentro de um diálogo modal. Não posso comentar mais sobre a correção da setTimeoutsolução sem conhecer os detalhes específicos de onde ela foi usada. No entanto, pensei em fornecer uma resposta aqui para ajudar as pessoas que se deparam com esse segmento, assim como eu fiz

O simples fato da questão é que você não pode se concentrar em um elemento que ainda não é visível . Se você enfrentar esse problema, verifique se o alvo está realmente visível quando é feita a tentativa de focalizá-lo. No meu próprio caso, eu estava fazendo algo nesse sentido

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

Isso não funcionou. Eu só percebi o que estava acontecendo quando eu executado $ ( '# elementID'). Focus () `a partir do console, que fez o trabalho. A diferença - no meu código acima do destino, não há certeza de que o destino será visível, pois a animação pode não estar completa . E aí está a pista

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

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

funciona exatamente como esperado. Eu também tinha inicialmente colocado uma setTimeoutsolução e funcionou também. No entanto, um tempo limite escolhido arbitrariamente é obrigado a interromper a solução mais cedo ou mais tarde, dependendo da velocidade com que o dispositivo host realiza o processo de garantir que o elemento de destino esteja visível.

DroidOS
fonte
A dica relevante para mim foi "garantir que o alvo seja realmente visível". isso se torna relevante ao tentar se concentrar em elementos renderizados condicionalmente.
Charlie Carver
Ou quando o elemento a ser focado visibility:hidden- ele não será focado.
bakrall 17/01
"você não pode se concentrar em um elemento que ainda não é visível" - eu te amo. Simplesmente adicionando um tempo limite de 100 ms, eu poderia ativar o foco na minha caixa de pesquisa oculta. Obrigado!
LuBre 30/01
Cuidado com os tempos limite. O que funciona na sua máquina de desenvolvimento pode não funcionar em outra.
DroidOS 30/01
15

se você usa o bootstrap + modal, isso funcionou para mim:

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

Apenas no caso de alguém mais se deparar com essa pergunta e ter a mesma situação que eu - eu estava tentando definir o foco depois de clicar em outro elemento, mas o foco não parecia funcionar. Acontece que eu só precisava de um e.preventDefault();- aqui está um exemplo:

$('#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();
});

Isso ajudou:

Se você chamar HTMLElement.focus () de um manipulador de eventos com o mouse, você deve chamar event.preventDefault () para impedir que o foco saia do HTMLElement. Fonte: https://developer.mozilla.org/en/docs/Web/API/HTMLElement/focus

Ben
fonte
2
O único funciona! Trigger é uma div pop-up, clique oculta a div e coloca algum valor em uma caixa de texto (não é necessário focar). Sem preventDefault, que a caixa de texto é sempre focada não importa o que -__-
rlatief
4

Sei que isso é antigo, mas me deparei hoje. Nenhuma das respostas funcionou para mim, o que eu achei que funcionou foi setTimeout. Eu queria que meu foco fosse colocado na entrada arquivada de um modal, usando o setTimeout trabalhado. Espero que isto ajude!

user3861385
fonte
Eu também! E a duração do tempo limite realmente fez a diferença. IE estúpido.
precisa saber é o seguinte
1
Mas não está funcionando em dispositivos móveis. Navegadores móveis estão ignorando, na maioria dos casos a tudo o que é setTimeout dentro
Kosmonaft
1
Como regra geral, usar setTimeouté uma solução ruim . Você não pode garantir o tempo de execução na máquina do usuário, portanto, as coisas dependentes do tempo são extremamente frágeis.
Nathan
3

Eu também tive esse problema. A solução que funcionou no meu caso foi usar a propriedade tabindex no elemento HTML.

Eu estava usando ng-repeatalguns elementos li dentro de uma lista e não consegui focar na primeira li usando .focus (), então simplesmente adicionei o atributo tabindex a cada li durante o loop.

então agora <li ng-repeat="user in users track by $index" tabindex="{{$index+1}}"></li>

O índice +1 foi iniciado a partir de 0. Verifique também se o elemento está presente no DOM antes de chamar a função .focus ()

Eu espero que isso ajude.

Kumar Shubham
fonte
2

Para aqueles com o problema de não funcionar porque você usou "$ (elemento) .show ()". Eu resolvi da seguinte maneira:

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

Portanto, você não precisa de um timer, ele será executado depois que o método show for concluído.

Rolando Retana
fonte
Isso se aplica a qualquer outra transição: slideDown(), fadeIn(), etc.
Álvaro González
2

Adicione um atraso antes do foco (). 200 ms é 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
fonte
0

Teve esse problema novamente agora, e, acredite ou não, tudo que eu precisava fazer era fechar as ferramentas do desenvolvedor. Aparentemente, a guia Console tem a prioridade do foco sobre o conteúdo da página.

aexl
fonte
0

Verifique se o elemento e seus pais estão visíveis. Você não pode usar o foco em elementos ocultos

mariovials
fonte
-1

SOLUÇÃO ADICIONAL Teve o mesmo problema em que o focus () parecia não funcionar, mas acabou por acontecer que o necessário era rolar para a posição correta:

Martin
fonte
-1

Para o meu caso, eu tive que especificar um índice de tabulação ( -1se possível apenas por script)

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