Gostaria de descobrir, em JavaScript, qual elemento atualmente tem foco. Estive pesquisando o DOM e ainda não encontrei o que preciso. Existe uma maneira de fazer isso e como?
A razão pela qual eu estava procurando isso:
Estou tentando criar teclas como as setas e enter
navegar por uma tabela de elementos de entrada. A guia funciona agora, mas digite, e as setas, por padrão, não parecem. Eu tenho a parte de manipulação de chaves configurada, mas agora preciso descobrir como mover o foco nas funções de manipulação de eventos.
javascript
dom
Tony Peterson
fonte
fonte
find-focused-element
pacote: npmjs.com/package/find-focused-elementRespostas:
Use
document.activeElement
, é suportado em todos os principais navegadores.Anteriormente, se você estivesse tentando descobrir qual campo do formulário tem foco, não poderia. Para emular a detecção em navegadores antigos, adicione um manipulador de eventos "focus" a todos os campos e registre o último campo focado em uma variável. Adicione um manipulador de "desfoque" para limpar a variável em um evento de desfoque para o último campo focado.
Se você precisar remover o,
activeElement
poderá usar o desfoque;document.activeElement.blur()
. Mudará oactiveElement
parabody
.Links Relacionados:
fonte
activeElement
na verdade, não retorna o elemento focado. Qualquer elemento pode ter foco. Se um documento tiver 4 'scrolldivs', 0 ou 1 dessas divs poderá ser rolado pelas teclas de seta. Se você clicar em um deles, essa div será focada. Se você clicar fora de tudo, o corpo estará focado. Como você descobre qual scrolldiv está focado? jsfiddle.net/rudiedirkx/bC5ke/show (console de verificação)div
é o Firefox 17, e apenas tabulando -o. Os tipos de elementos pelos quais TODOS os principais navegadores retornamdocument.activeElement
estão restritos a elementos relacionados à entrada . Se nenhum desses elementos tiver o foco, todos os principais navegadores retornarão obody
elemento - exceto o IE 9, que retorna ohtml
elemento.document.activeElement
deve ser agrupado de uma maneiratry catch
que, em algumas circunstâncias, pode gerar uma exceção (não apenas o IE9 AFAIK). Veja bugs.jquery.com/ticket/13393 e bugs.jqueryui.com/ticket/8443Como dito pela JW, não é possível encontrar o elemento atual focado, pelo menos de maneira independente do navegador. Mas se o seu aplicativo for apenas o IE (alguns são ...), você poderá encontrá-lo da seguinte maneira:
EDIT: Parece que o IE não tinha tudo errado, afinal, isso faz parte do rascunho do HTML5 e parece ser suportado pela versão mais recente do Chrome, Safari e Firefox, pelo menos.
fonte
Se você pode usar o jQuery, agora ele suporta: focus, apenas verifique se você está usando a versão 1.6+.
Esta declaração fornecerá o elemento atualmente focado.
De: como selecionar um elemento que se concentre nele com o jQuery
fonte
return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
document.activeElement
agora faz parte da especificação de rascunho de trabalho do HTML5 , mas ainda pode não ser suportada em alguns navegadores não principais / móveis / mais antigos. Você pode voltar aquerySelector
(se houver suporte). Também vale a pena mencionar quedocument.activeElement
retornarádocument.body
se nenhum elemento estiver focado - mesmo que a janela do navegador não tenha foco.O código a seguir resolverá esse problema e voltará a
querySelector
oferecer um suporte um pouco melhor.Outro aspecto a ser observado é a diferença de desempenho entre esses dois métodos. Consultar o documento com seletores sempre será muito mais lento que acessar a
activeElement
propriedade. Veja este teste do jsperf.com .fonte
Por si só,
document.activeElement
ainda pode retornar um elemento se o documento não estiver focado (e, portanto, nada no documento estiver focado!)Você pode querer esse comportamento, ou ele pode não importar (por exemplo, dentro de um
keydown
evento), mas se precisar saber que algo está realmente focado, você pode verificar adicionalmentedocument.hasFocus()
.A seguir, você fornece o elemento focado, se houver um, ou então
null
.Para verificar se um elemento específico tem foco, é mais simples:
Para verificar se alguma coisa está focada, é mais complexo novamente:
Robustez Nota : no código em que ele faz a verificação
document.body
edocument.documentElement
, isso ocorre porque alguns navegadores retornam um desses ounull
quando nada está focado.Não explica se o
<body>
(ou talvez<html>
) tinha umtabIndex
atributo e, portanto, poderia realmente ser focado . Se você estiver escrevendo uma biblioteca ou algo assim e quiser que ela seja robusta, provavelmente deve lidar com isso de alguma forma.Aqui está uma ( pesados airquotes) versão "one-liner" de conseguir o elemento focalizado, que é conceitualmente mais complicado porque você tem que saber sobre curto-circuito, e você sabe, é óbvio que não se encaixa em uma linha, supondo que você quer que seja legível.
Eu não vou recomendar este. Mas se você é um 1337 hax0r, idk ... está lá.
Você também pode remover a
|| null
peça se não se importarfalse
em receber alguns casos. (Você ainda pode obternull
sedocument.activeElement
fornull
):Para verificar se um elemento específico está focado, como alternativa, você pode usar eventos, mas dessa maneira requer configuração (e potencialmente desmontagem) e, o que é mais importante, assume um estado inicial :
Você pode corrigir a suposição de estado inicial usando a maneira não-evento, mas também pode usá-la.
fonte
document.activeElement
pode usar como padrão o<body>
elemento se nenhum elemento focalizável estiver em foco. Além disso, se um elemento estiver focado e a janela do navegador estiver embaçada,activeElement
continuará mantendo o elemento focado.Se qualquer um destes dois comportamentos não são desejáveis, considere uma abordagem baseada em CSS:
document.querySelector( ':focus' )
.fonte
querySelector
: stackoverflow.com/a/40873560/2624876Gostei da abordagem usada por Joel S, mas também adoro a simplicidade de
document.activeElement
. Eu usei o jQuery e combinei os dois. Navegadores mais antigos que não suportamdocument.activeElement
usarãojQuery.data()
para armazenar o valor de 'hasFocus'. Navegadores mais recentes usarãodocument.activeElement
. Presumo quedocument.activeElement
terá melhor desempenho.fonte
$("*:focus")
?Um pequeno ajudante que usei para esses fins no Mootools:
Dessa forma, você pode verificar se o elemento está focado,
el.hasFocus()
desde questartFocusTracking()
tenha sido chamado no elemento especificado.fonte
O JQuery suporta a
:focus
pseudo-classe a partir da atual. Se você está procurando na documentação do JQuery, verifique em "Seletores", onde ele aponta os documentos CSS do W3C . Eu testei com Chrome, FF e IE 7+. Observe que, para que ele funcione no IE,<!DOCTYPE...
deve existir na página html. Aqui está um exemplo, assumindo que você atribuiu um ID ao elemento que tem o foco:fonte
this.id
vez de$(this).attr('id')
, ou pelo menos (quando você já possui seu objeto jQuery)$(this)[0].id
. Javascript nativo neste nível é MUITO mais rápido e mais eficiente. Pode não ser perceptível neste caso, mas em todo o sistema você notará uma diferença.Se você deseja obter um objeto que é instância
Element
, você deve usardocument.activeElement
, mas se você deseja obter um objeto que é instânciaText
, deve usardocument.getSelection().focusNode
.Espero que ajude.
fonte
document.getSelection().focusNode.parentElement
e toque em Enter. Depois disso, passedocument.activeElement
e faça o mesmo. ;)document.activeElement
dá o<textarea>
passo quedocument.getSelection().focusNode
dá o<td>
que contém o<textarea>
(edocument.getSelection().focusNode.parentElement
dá o<tr>
que contém a<td>
)Element
, é necessário usá-lodocument.activeElement
, mas se deseja obter um objeto que é instânciaText
, é necessário usá-lodocument.getSelection().focusNode
. Por favor, teste novamente. Espero ter ajudado.focusNode
também não é garantido que seja um nó de texto.Existem problemas em potencial com o uso de document.activeElement. Considerar:
Se o usuário se concentrar em uma div interna, document.activeElement ainda fará referência à div externa. Você não pode usar document.activeElement para determinar qual das divs internas tem foco.
A seguinte função contorna isso e retorna o nó focado:
Se você preferir obter o elemento focado, use:
fonte
document.activeElement
: os<div>
elementos internos realmente não podem receber o foco, como você pode ver visualmente, definindo a:focus
pseudo-classe como algo visível (exemplo: jsfiddle.net/4gasa1t2/1 ). O que você está falando é qual dos<div>
s internos contém a seleção ou o sinal de intercalação, que é uma questão separada.Eu achei o seguinte snippet útil ao tentar determinar qual elemento atualmente tem foco. Copie o seguinte no console do seu navegador e, a cada segundo, ele imprimirá os detalhes do elemento atual em foco.
Sinta-se à vontade para modificar o
console.log
item para fazer logout de algo diferente para ajudá-lo a identificar o elemento exato se a impressão de todo o elemento não o ajudar a identificar o elemento.fonte
Lendo outras respostas e tentando a mim mesmo, parece
document.activeElement
que você fornecerá o elemento necessário na maioria dos navegadores.Se você possui um navegador que não suporta document.activeElement, se você tem jQuery por perto, deve poder preenchê-lo em todos os eventos de foco com algo muito simples como este (não testado, pois eu não tenho um navegador que atenda a esses critérios à mão) ):
fonte
Se você estiver usando jQuery, poderá usá-lo para descobrir se um elemento está ativo:
fonte
Com o dojo, você pode usar dijit.getFocus ()
fonte
Basta colocar isso aqui para dar a solução que eu acabei encontrando.
Criei uma propriedade chamada document.activeInputArea e usei o complemento HotKeys do jQuery para capturar eventos de teclado para teclas de seta, tab e enter, e criei um manipulador de eventos para clicar nos elementos de entrada.
Depois, eu ajustava o activeInputArea toda vez que o foco era alterado, para que eu pudesse usar essa propriedade para descobrir onde estava.
É fácil estragar tudo, porque se você tem um erro no sistema e o foco não está onde você pensa, é muito difícil restaurar o foco correto.
fonte