Existe alguma maneira de verificar se um elemento é visível em JS puro (sem jQuery)?
Então, por exemplo, nesta página: Bicicletas de desempenho , se você passar o mouse sobre Ofertas (no menu superior), uma janela de ofertas aparecerá, mas no começo ela não foi exibida. Está no HTML, mas não é visível.
Portanto, dado um elemento DOM, como posso verificar se é visível ou não? Eu tentei:
window.getComputedStyle(my_element)['display']);
mas não parece estar funcionando. Gostaria de saber quais atributos devo verificar. Isso vem à minha mente:
display !== 'none'
visibility !== 'hidden'
Algum outro que eu possa estar perdendo?
javascript
dom
Hommer Smith
fonte
fonte
document.getElementById('snDealsPanel').style.visibility
Respostas:
De acordo com esta documentação do MDN , a
offsetParent
propriedade de um elemento retornaránull
sempre que ele ou qualquer um de seus pais estiver oculto pela propriedade de estilo de exibição. Apenas verifique se o elemento não está fixo. Um script para verificar isso, se você não tiverposition: fixed;
elementos em sua página, pode se parecer com:Por outro lado, se você não tem elementos de posição fixa que pode ser pego nessa busca, você vai, infelizmente (e lentamente) tem que usar
window.getComputedStyle()
. A função nesse caso pode ser:A opção 2 é provavelmente um pouco mais direta, pois é responsável por mais casos extremos, mas aposto que é muito mais lento também; portanto, se você precisar repetir essa operação muitas vezes, é melhor evitá-la.
fonte
el.offsetParent
não estava funcionando no IE9 para elementos não fixos. Ou pelo menos parece. (OK para o IE11, no entanto)getComputedStyle
.getComputedStyle
não funciona corretamente: plnkr.co/edit/6CSCA2fe4Gqt4jCBP2wu?p=preview No entanto, o mesmo aconteceoffsetParent
- talvez uma combinação dos dois deva ser usada?Todas as outras soluções quebraram para alguma situação para mim ..
Veja a resposta vencedora em:
http://plnkr.co/edit/6CSCA2fe4Gqt4jCBP2wu?p=preview
Por fim, decidi que a melhor solução era
$(elem).is(':visible')
- no entanto, esse não é um javascript puro. é jquery ..então eu espiei a fonte deles e encontrei o que queria
Esta é a fonte: https://github.com/jquery/jquery/blob/master/src/css/hiddenVisibleSelectors.js
fonte
true
para um elemento comvisibility:hidden
visibility:hidden
não mostra mais conteúdo, mas ainda ocupa a largura e a altura do elemento!Se você estiver interessado em ser visível pelo usuário:
Testado em (usando a terminologia mocha ):
fonte
scrollIntoView
direito ?! Isso é muito caro. Existe outra maneira inteligente?Isso pode ajudar: Esconda o elemento posicionando-o na posição mais à esquerda e verifique a propriedade offsetLeft. Se você deseja usar o jQuery, basta verificar : seletor e obter o estado de visibilidade do elemento.
HTML:
CSS:
javaScript:
jQuery:
jsFiddle
fonte
Use o mesmo código que o jQuery:
Então, em uma função:
Funciona como um encanto no meu Win / IE10, Linux / Firefox.45, Linux / Chrome.52 ...
Muito obrigado ao jQuery sem o jQuery!
fonte
e.offsetWidth
é um número inteiro,!e.offsetWidth
retornaráfalse
see.offsetWidth
for maior que zero (o elemento é visível). Portanto, adicionar outro!
como em!!e.offsetWidth
retornarátrue
see.offsetWidth
for maior que zero. É uma abreviação parareturn e.offsetWidth > 0 ? true : false
ou obviamentereturn e.offsetWidth > 0
.Combinando algumas respostas acima:
Como AlexZ disse, isso pode ser mais lento do que algumas de suas outras opções, se você souber mais especificamente o que está procurando, mas isso deve capturar todas as principais maneiras pelas quais os elementos estão ocultos.
Mas também depende do que é visível para você. Apenas por exemplo, a altura de uma div pode ser definida como 0px, mas o conteúdo ainda é visível, dependendo das propriedades do estouro. Ou o conteúdo de uma div pode ter a mesma cor do plano de fundo, para que não fique visível para os usuários, mas ainda seja renderizado na página. Ou uma div pode ser movida para fora da tela ou oculta por trás de outras divs, ou seu conteúdo pode não ser visível, mas a borda ainda visível. Até certo ponto, "visível" é um termo subjetivo.
fonte
display:none
a isso seria ótimo. Uma solução de trabalho adequada!Eu tenho uma solução com melhor desempenho em comparação com a solução getComputedStyle () da AlexZ quando alguém tem elementos de posição 'fixos', se estiver disposto a ignorar alguns casos extremos (verifique os comentários):
Nota lateral: Estritamente falando, a "visibilidade" precisa ser definida primeiro. No meu caso, estou considerando um elemento visível, desde que eu possa executar todos os métodos / propriedades do DOM nele sem problemas (mesmo se a opacidade for 0 ou a propriedade de visibilidade CSS estiver 'oculta' etc.).
fonte
Se o elemento estiver visível regularmente (display: block e visibillity: visible), mas algum contêiner pai estiver oculto, podemos usar clientWidth e clientHeight para verificar isso.
Plunker (clique aqui)
fonte
ele.style.visibility !== 'hidden'
é redundante aqui. Nesse caso, clientWidth e clientHeight será 0.Se estamos apenas coletando maneiras básicas de detectar visibilidade, não esqueço:
E sobre como obter atributos:
Então, no seu exemplo:
Mas o que? Não funciona aqui. Olhe mais de perto e você verá que a visibilidade está sendo atualizada não como um atributo no elemento, mas usando a
style
propriedade Esse é um dos muitos problemas ao tentar fazer o que você está fazendo. Entre outros: você não pode garantir que realmente haja algo para ver em um elemento, apenas porque sua visibilidade, exibição e opacidade têm os valores corretos. Ele ainda pode não ter conteúdo ou pode não ter altura e largura. Outro objeto pode obscurecê-lo. Para mais detalhes, uma rápida pesquisa no Google revela isso e até inclui uma biblioteca para tentar resolver o problema. (YMMV)Confira o seguinte, que são possíveis duplicatas desta pergunta, com excelentes respostas, incluindo algumas dicas do poderoso John Resig. No entanto, seu caso de uso específico é um pouco diferente do padrão, portanto evitarei sinalizar:
(EDIT: OP diz que ele está raspando páginas, não as criando, então abaixo não é aplicável) Uma opção melhor? Vincule a visibilidade dos elementos às propriedades do modelo e sempre torne a visibilidade contingente nesse modelo, da mesma forma que o Angular faz com o ng-show. Você pode fazer isso usando qualquer ferramenta que desejar: JS angular e simples, qualquer que seja. Melhor ainda, você pode alterar a implementação do DOM ao longo do tempo, mas sempre poderá ler o estado do modelo, em vez do DOM. Ler a sua verdade a partir do DOM é ruim. E devagar. Muito melhor verificar o modelo e confiar na sua implementação para garantir que o estado do DOM reflita o modelo. (E use o teste automatizado para confirmar essa suposição.)
fonte
A resposta aceita não funcionou para mim. Resposta do ano 2020 :
1) O método (elem.offsetParent! == null) funciona bem no Firefox, mas não no Chrome. Para o Chrome "position: fixed;" também fará com que offsetParent retorne "null", mesmo o elemento se visível na página.
Demo:
você pode ver esse cara megatest https://stackoverflow.com/a/11639664/4481831 (execute-o com vários navegadores para ver as diferenças).
2) O (getComputedStyle (elem) .display! == 'none') não funciona porque o elemento pode ser invisível porque uma das propriedades de exibição dos pais está configurada como none, getComputedStyle não irá capturar isso.
Demo:
3) O (elem.clientHeight! == 0) . Este método não é influenciado pela posição fixa e também verifica se os pais do elemento não são visíveis. Mas tem problemas com elementos simples que não têm um layout css, veja mais aqui
Demo:
4) Os (elem.getClientRects (). Length! == 0) que parecem ultrapassar os problemas dos três métodos anteriores. No entanto, há problemas com elementos que usam truques CSS (exceto "display: none") para ocultar na página.
CONCLUSÃO: Então, o que eu mostrei é que nenhum método é perfeito. Para fazer uma verificação de visibilidade adequada, você deve usar uma combinação dos três últimos métodos.
fonte
Apenas para referência, note-se que
getBoundingClientRect()
pode funcionar em certos casos.Por exemplo, uma verificação simples de que o elemento está oculto
display: none
pode se parecer com o seguinte:Isso também é útil, pois também abrange largura zero, altura zero e
position: fixed
estojos. No entanto, ele não deve relatar elementos ocultos comopacity: 0
ouvisibility: hidden
(mas nem o fariaoffsetParent
).fonte
var isVisible = el => (r => r.width && r.height)(el.getBoundingClientRect());
. Em seguida, pode filtrar matrizes de elementos da seguinte maneira:$$(sel).filter(isVisible)
.Então, o que eu achei é o método mais viável:
Isso se baseia nesses fatos:
display: none
elemento (mesmo um aninhado) não tem largura nem altura.visiblity
éhidden
uniforme para elementos aninhados.Portanto, não há necessidade de testar
offsetParent
ou fazer um loop na árvore DOM para testar qual pai possuivisibility: hidden
. Isso deve funcionar mesmo no IE 9.Você poderia argumentar se
opacity: 0
e os elementos recolhidos (tem largura, mas não altura - ou vice-versa) também não são realmente visíveis. Mas, novamente, eles não estão escondidos.fonte
Um pequeno acréscimo à resposta do ohad navon.
Se o centro do elemento pertencer a outro elemento, não o encontraremos.
Portanto, para garantir que um dos pontos do elemento seja visível
fonte
Melhorando a resposta de @Guy Messika acima , quebrando e retornando false se o ponto central 'X for <0 estiver errado, pois o elemento do lado direito pode entrar na visualização. aqui está uma correção:
fonte
O código jQuery de http://code.jquery.com/jquery-1.11.1.js possui um parâmetro isHidden
Parece que há uma verificação extra relacionada ao documento do proprietário
Gostaria de saber se isso realmente captura os seguintes casos:
fonte
Aqui está o código que escrevi para encontrar o único visível entre alguns elementos semelhantes e retornar o valor do atributo "class" sem o jQuery:
fonte
Isto é o que eu fiz:
HTML e CSS: ocultou o elemento por padrão
JavaScript: Adicionado um código para verificar se a visibilidade está oculta ou não:
fonte
Esta é uma maneira de determiná-lo para todas as propriedades do CSS, incluindo a visibilidade:
html:
css:
javascript:
Ele funciona para qualquer propriedade css e é muito versátil e confiável.
fonte