¿Hay alguna manera de verificar si un elemento es visible en JS puro (no jQuery)?
Entonces, por ejemplo, en esta página: Bicicletas de rendimiento , si pasa el cursor sobre Ofertas (en el menú superior), aparece una ventana de ofertas, pero al principio no se mostraba. Está en el HTML pero no es visible.
Entonces, dado un elemento DOM, ¿cómo puedo verificar si está visible o no? Lo intenté:
window.getComputedStyle(my_element)['display']);
Pero no parece estar funcionando. Me pregunto qué atributos debo verificar. Me viene a la mente:
display !== 'none'
visibility !== 'hidden'
¿Algún otro que pueda estar perdiendo?
javascript
dom
Hommer Smith
fuente
fuente
document.getElementById('snDealsPanel').style.visibility
Respuestas:
De acuerdo con esta documentación de MDN , la
offsetParent
propiedad de un elemento volveránull
siempre que ésta, o cualquiera de sus padres, esté oculta a través de la propiedad de estilo de visualización. Solo asegúrese de que el elemento no sea fijo. Un script para verificar esto, si no tieneposition: fixed;
elementos en su página, podría verse así:Por otro lado, si usted no tiene elementos de posición fija que puedan engancharse en esta búsqueda, se le lamentablemente (y poco a poco) tienen que usar
window.getComputedStyle()
. La función en ese caso podría ser:La opción n. ° 2 probablemente sea un poco más sencilla, ya que representa más casos extremos, pero apuesto a que también es mucho más lenta, por lo que si tiene que repetir esta operación muchas veces, lo mejor es evitarla.
fuente
el.offsetParent
no funcionaba en IE9 para elementos no fijos. O eso parece, de todos modos. (OK para IE11, sin embargo). Así que seguí congetComputedStyle
después de todo.getComputedStyle
no funciona correctamente: plnkr.co/edit/6CSCA2fe4Gqt4jCBP2wu?p=preview Sin embargo, también lo haceoffsetParent
, ¿quizás debería usarse una combinación de los dos?Todas las otras soluciones se rompieron para alguna situación para mí ...
Vea la respuesta ganadora rompiendo en:
http://plnkr.co/edit/6CSCA2fe4Gqt4jCBP2wu?p=preview
Finalmente, decidí que la mejor solución era
$(elem).is(':visible')
, sin embargo, esto no es puro javascript. es jquery ..así que eché un vistazo a su fuente y encontré lo que quería
Esta es la fuente: https://github.com/jquery/jquery/blob/master/src/css/hiddenVisibleSelectors.js
fuente
true
para un elemento convisibility:hidden
visibility:hidden
ya no muestre contenido, pero aún toma el ancho y la altura del elemento!Si está interesado en visible por el usuario:
Probado en (usando terminología moca ):
fuente
scrollIntoView
derecho? Esto es bastante costoso. ¿Hay otra manera inteligente?Esto puede ayudar: Ocultar el elemento colocándolo en la posición más a la izquierda y luego verificar la propiedad offsetLeft. Si desea usar jQuery, simplemente puede verificar el : selector visible y obtener el estado de visibilidad del elemento.
HTML:
CSS:
javaScript:
jQuery:
jsFiddle
fuente
Use el mismo código que jQuery:
Entonces, en una función:
Funciona como un encanto en mi Win / IE10, Linux / Firefox.45, Linux / Chrome.52 ...
Muchas gracias a jQuery sin jQuery!
fuente
e.offsetWidth
es un entero,!e.offsetWidth
regresaráfalse
sie.offsetWidth
es mayor que cero (el elemento es visible). Por lo tanto, agregar otro!
como en!!e.offsetWidth
devolverátrue
sie.offsetWidth
es mayor que cero. Es una abreviatura para,return e.offsetWidth > 0 ? true : false
o obviamentereturn e.offsetWidth > 0
.Combinando un par de respuestas anteriores:
Como dijo AlexZ, esto puede ser más lento que algunas de sus otras opciones si sabe más específicamente lo que está buscando, pero esto debería captar todas las formas principales en que los elementos están ocultos.
Pero también depende de lo que cuenta como visible para usted. Solo por ejemplo, la altura de un div se puede establecer en 0px pero los contenidos siguen siendo visibles dependiendo de las propiedades de desbordamiento. O bien, el contenido de un div podría tener el mismo color que el fondo para que no sea visible para los usuarios pero aún se visualice en la página. O un div podría moverse fuera de la pantalla u ocultarse detrás de otros divs, o su contenido podría no ser visible pero el borde aún visible. Hasta cierto punto "visible" es un término subjetivo.
fuente
display:none
a esto sería genial. ¡Una solución de trabajo adecuada!Tengo una solución más eficaz en comparación con la solución getComputedStyle () de AlexZ cuando uno tiene elementos de posición 'fijos', si está dispuesto a ignorar algunos casos extremos (verifique los comentarios):
Nota al margen: Estrictamente hablando, la "visibilidad" debe definirse primero. En mi caso, estoy considerando un elemento visible siempre que pueda ejecutar todos los métodos / propiedades DOM sin problemas (incluso si la opacidad es 0 o la propiedad de visibilidad CSS está 'oculta', etc.).
fuente
Si el elemento es visible regularmente (display: block y visibillity: visible), pero algún contenedor padre está oculto, entonces podemos usar clientWidth y clientHeight para verificar eso.
Plunker (haga clic aquí)
fuente
ele.style.visibility !== 'hidden'
Es redundante aquí. En ese caso, clientWidth y clientHeight serán 0.Si solo estamos recopilando formas básicas de detectar la visibilidad, no me olvides:
Y en cuanto a cómo obtener atributos:
Entonces, en tu ejemplo:
Pero que? No funciona aqui. Mire más de cerca y verá que la visibilidad se está actualizando no como un atributo en el elemento, sino usando la
style
propiedad. Este es uno de los muchos problemas al intentar hacer lo que estás haciendo. Entre otros: no puede garantizar que realmente haya algo que ver en un elemento, solo porque su visibilidad, visualización y opacidad tienen los valores correctos. Todavía puede carecer de contenido, o puede carecer de altura y anchura. Otro objeto podría oscurecerlo. Para más detalles, una búsqueda rápida en Google revela esto , e incluso incluye una biblioteca para tratar de resolver el problema. (YMMV)Eche un vistazo a lo siguiente, que son posibles duplicados de esta pregunta, con excelentes respuestas, que incluyen algunas ideas del poderoso John Resig. Sin embargo, su caso de uso específico es ligeramente diferente del estándar, por lo que me abstendré de marcar:
(EDITAR: OP DICE QUE ESTÁ RASGANDO PÁGINAS, NO LOS CREA, ASÍ QUE NO ES APLICABLE A CONTINUACIÓN) ¿Una mejor opción? Vincula la visibilidad de los elementos a las propiedades del modelo y siempre haz que la visibilidad dependa de ese modelo, al igual que Angular hace con ng-show. Puede hacerlo usando cualquier herramienta que desee: JS angular, simple, lo que sea. Mejor aún, puede cambiar la implementación del DOM con el tiempo, pero siempre podrá leer el estado del modelo, en lugar del DOM. Leer tu verdad desde el DOM es malo. Y lento Es mucho mejor verificar el modelo y confiar en su implementación para garantizar que el estado DOM refleje el modelo. (Y use pruebas automatizadas para confirmar esa suposición).
fuente
La respuesta aceptada no funcionó para mí. Respuesta del año 2020 :
1) El método (elem.offsetParent! == null) funciona bien en Firefox pero no en Chrome. Para Chrome "posición: fija;" también hará que offsetParent devuelva "nulo" incluso el elemento si es visible en la página.
Manifestación:
Puedes ver este chico megatest https://stackoverflow.com/a/11639664/4481831 ( ejecútalo con múltiples navegadores para ver las diferencias).
2) (getComputedStyle (elem) .display! == 'none') no funciona porque el elemento puede ser invisible porque una de las propiedades de visualización de los padres está establecida en none, getComputedStyle no detectará eso.
Manifestación:
3) El (elem.clientHeight! == 0) . Este método no está influenciado por la posición fija y también verifica si los elementos primarios no son visibles. Pero tiene problemas con elementos simples que no tienen un diseño CSS, vea más aquí
Manifestación:
4) Los (elem.getClientRects (). Length! == 0) que parecen superar los problemas de los 3 métodos anteriores. Sin embargo, tiene problemas con los elementos que usan trucos CSS (aparte de "display: none") para esconderse en la página.
CONCLUSIÓN: Entonces, lo que te he mostrado es que ningún método es perfecto. Para realizar una verificación de visibilidad adecuada, debe usar una combinación de los últimos 3 métodos.
fuente
Solo como referencia, debe tenerse en cuenta que
getBoundingClientRect()
puede funcionar en ciertos casos.Por ejemplo, una simple comprobación de que el elemento está oculto usando
display: none
podría verse algo así:Esto también es útil porque también cubre ancho cero, altura cero y
position: fixed
casos. Sin embargo, no informará elementos ocultos conopacity: 0
ovisibility: hidden
(pero tampoco lo haríaoffsetParent
).fuente
var isVisible = el => (r => r.width && r.height)(el.getBoundingClientRect());
. Entonces puedo filtrar conjuntos de elementos de la siguiente manera:$$(sel).filter(isVisible)
.Entonces, lo que encontré es el método más factible:
Esto se basa en estos hechos:
display: none
elemento (incluso uno anidado) no tiene ancho ni alto.visiblity
eshidden
incluso para elementos anidados.Por lo tanto, no es necesario realizar pruebas
offsetParent
o bucles en el árbol DOM para probar qué padre tienevisibility: hidden
. Esto debería funcionar incluso en IE 9.Podría argumentar si los
opacity: 0
elementos colapsados (tiene un ancho pero no alto, o viceversa) tampoco son realmente visibles. Pero, de nuevo, no están ocultos.fuente
Una pequeña adición a la respuesta de ohad navon.
Si el centro del elemento pertenece al otro elemento, no lo encontraremos.
Entonces, para asegurarse de que uno de los puntos del elemento sea visible
fuente
Mejorando la respuesta anterior de @Guy Messika , rompiendo y devolviendo falso si el punto central 'X es <0 es incorrecto ya que el elemento del lado derecho puede entrar en la vista. Aquí hay una solución:
fuente
El código jQuery de http://code.jquery.com/jquery-1.11.1.js tiene un parámetro isHidden
Parece que hay un control adicional relacionado con el documento del propietario
Me pregunto si esto realmente atrapa los siguientes casos:
fuente
Aquí está el código que escribí para encontrar el único visible entre algunos elementos similares, y devolver el valor de su atributo "class" sin jQuery:
fuente
Esto es lo que hice:
HTML y CSS: hizo el elemento oculto por defecto
JavaScript: se agregó un código para verificar si la visibilidad está oculta o no:
fuente
Esta es una forma de determinarlo para todas las propiedades css, incluida la visibilidad:
html:
css:
javascript:
Funciona para cualquier propiedad css y es muy versátil y confiable.
fuente