É possível focar em uma <div> usando a função JavaScript focus ()?

227

É possível se concentrar em <div>usar a focus()função JavaScript ?

Eu tenho uma <div>etiqueta

<div id="tries">You have 3 tries left</div>

Estou tentando focar no acima <div>usando:

document.getElementById('tries').focus();

Mas isso não funciona. Alguém poderia sugerir algo ....?

OM a eternidade
fonte
3
O que você quer que aconteça quando o 'focaliza'? Divs não aceitam entrada, então você quer piscar a borda ou piscar um destaque de fundo etc?
Michael Shimmins
@ Michael, sim, eu preciso que <div> para buscar a atenção do usuário ...
OM O Eternity
1
possível duplicação de Quais elementos HTML podem receber o foco?
Ciro Santilli escreveu
1
@MichaelShimmins e qualquer outra pessoa, os elementos <div> podem aceitar entrada se você tiver definido o conteúdo definido como true. (Razão pela qual eu perguntei)
MattOlivos
1
@MichaelShimmins divs pode aceitar entrada se estourarem e mostrarem uma barra de rolagem. Quando um divcom uma barra de rolagem é focado, as teclas de seta rolam seu conteúdo (em vez do conteúdo de outros elementos, como body).
Rory O'Kane

Respostas:

101
window.location.hash = '#tries';

Isso irá rolar para o elemento em questão, essencialmente "focando" nele.

Casey Chu
fonte
2
@Casey Chu: Está funcionando bem no ie, mas não no firefox, você tem alguma ideia?
Haseeb Akhtar
Ele não funciona em algumas versões do Chrome ... No entanto, a solução @vinoths funciona #
Charliemops 14/11
1
Isso funciona, mas ... com o Angular você teria problemas!
Carlos Verdes
@CarlosVerdes; Existe uma solução para o Angular?
Mac Vicious
3
não responder à pergunta 'foco', essa não deve ser a resposta correta. no meu caso, quero me concentrar em uma div 'contentEditable' e seu truque não ajuda.
Arnaudambro 06/06/19
453

Sim - isso é possível. Para fazer isso, você precisa atribuir um índice de tabulação ...

<div tabindex="0">Hello World</div>

Um índice de tabulação 0 colocará a tag "na ordem de tabulação natural da página". Um número maior dará a ele uma ordem específica de prioridade, onde 1 será o primeiro, 2 segundos e assim por diante.

Você também pode fornecer um índice de tabulação -1, que tornará a div apenas focável por script, não pelo usuário.

document.getElementById('test').onclick = function () {
    document.getElementById('scripted').focus();
};
div:focus {
    background-color: Aqua;
}
<div>Element X (not focusable)</div>
<div tabindex="0">Element Y (user or script focusable)</div>
<div tabindex="-1" id="scripted">Element Z (script-only focusable)</div>
<div id="test">Set Focus To Element Z</div>

Obviamente, é uma pena ter um elemento que você possa focar por script que não possa ser focado por outro método de entrada (especialmente se um usuário tiver apenas o teclado ou restrições semelhantes). Também há vários elementos padrão que são focáveis ​​por padrão e possuem informações semânticas incorporadas para ajudar os usuários. Use esse conhecimento com sabedoria.

Fenton
fonte
6
@ Michael Shimmins, Isso permite que o elemento seja focalizável (de maneira não padronizada!) focus().
strager
2
@ Oical - Tenho certeza de que é exatamente o que diz na última linha de maio de resposta. Deixe-me saber se você acha que há um problema que precisa de uma edição.
Fenton
2
Se não fosse clara, adicionando tabindexa um elemento irá torná-lo focalizável, que permite que os focus()e blur()métodos, e então você pode desencadear um foco assim:document.getElementById('tries').focus();
pilau
4
Olá @SteveOwen - parece que ainda funciona no Firefox v42. Adicionei um trecho a esta resposta para que você possa executá-lo e testá-lo.
Fenton
9
@SteveOwen usando window.location.hash = ...é a maneira de fazer isso. foco não significa "trazer à vista", significa apenas colocar literalmente o foco nesse elemento.
Fenton
76

document.getElementById('tries').scrollIntoView()trabalho. Isso funciona melhor do que window.location.hash quando você tem um posicionamento fixo.

vinoths
fonte
2
Observe que esta solução não funcionará no IE, Opera ou Safari.
AlecRust 25/09
1
Eu apenas tentei isso no Chrome 65 e ele não funciona. A div de sobreposição é exibida, mas o foco ainda está na div de fundo. A única maneira certa de que conheço é ter um elemento tabable (usando tabindexatributo) na div de sobreposição e usá focus()-lo nesse elemento.
Thdiran
@ om-the-eternity já declarou que ele quer que a div chame a atenção do usuário, então o que ele precisa não é realmente focar (mesmo quando estiver trabalhando não é correto fazê-lo) a div, mas trazê-la para a tela , este resolve esse
Omar Vazquez
Se eu fizer isso no Chrome, ele continuará rolando de volta para o campo de entrada ainda focado. Especialmente se a página ainda não tiver sido carregada.
Roger Krueger
37

Você pode usar tabindex

<div tabindex="-1"  id="tries"></div>

O valor tabindex pode permitir algum comportamento interessante.

  • Se for fornecido um valor de "-1", o elemento não poderá ser tabulado, mas o foco poderá ser atribuído ao elemento programaticamente (usando element.focus ()).
  • Se o valor for 0, o elemento pode ser focado pelo teclado e cair no fluxo de tabulação do documento. Valores maiores que 0 criam um nível de prioridade, sendo 1 o mais importante.
Sarath Ak
fonte
1
Uau, obrigado truque legal. Obrigado! Eu não teria descoberto isso de outra maneira.
AVProgrammer
Economizador de vida, obrigado. No Edge, uma div pode ser focada, mas não no Chrome, sem esse truque. A resposta aceita é ótima, mas não quero uma parte adicional no URL.
Cal
salvar a vida.Funciona bem com chrome e firefox
Susampath
14
<div id="inner" tabindex="0">
    this div can now have focus and receive keyboard events
</div>
Azad
fonte
Isso funciona para mim no Chromium / Chrome 46 apenas combinado com$('#inner').focus();
TNT
2

Eu queria sugerir algo como o de Michael Shimmin, mas sem codificar coisas como o elemento ou o CSS aplicado a ele.

Eu só estou usando jQuery para adicionar / remover classe, se você não quiser usar jquery, você só precisa de um substituto para add / removeClass

--Javascript

function highlight(el, durationMs) { 
  el = $(el);
  el.addClass('highlighted');
  setTimeout(function() {
    el.removeClass('highlighted')
  }, durationMs || 1000);
}

highlight(document.getElementById('tries'));

--CSS

#tries {
    border: 1px solid gray;
}

#tries.highlighted {
    border: 3px solid red;
}
Juan Mendes
fonte
1

document.getElementById('test').onclick = function () {
    document.getElementById('scripted').focus();
};
div:focus {
    background-color: Aqua;
}
<div>Element X (not focusable)</div>
<div tabindex="0">Element Y (user or script focusable)</div>
<div tabindex="-1" id="scripted">Element Z (script-only focusable)</div>
<div id="test">Set Focus To Element Z</div>

San Jing
fonte
0

Para fazer a borda piscar, você pode fazer isso:

function focusTries() {
    document.getElementById('tries').style.border = 'solid 1px #ff0000;'
    setTimeout ( clearBorder(), 1000 );
}

function clearBorder() {
    document.getElementById('tries').style.border = '';
}

Isso fará com que a borda fique vermelha por 1 segundo e remova-a novamente.

Michael Shimmins
fonte