una tablas tabla saber modal esta elemento ejemplos ejemplo datos con agregar abierto javascript dom

tablas - saber si un elemento es visible javascript



Compruebe si el elemento es visible en DOM (17)

¿Hay alguna manera de que pueda verificar si un elemento es visible en JS puro (no jQuery)?

Entonces, por ejemplo, en esta página: Bicicletas de rendimiento , si pasa el mouse 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 comprobar. Me viene a la mente:

display !== ''none'' visibility !== ''hidden''

¿Algún otro que pueda faltar?


Aquí está el código que escribí para encontrar el único visible entre unos pocos elementos similares y devolver el valor de su atributo "clase" sin jQuery:

// Build a NodeList: var nl = document.querySelectorAll(''.myCssSelector''); // convert it to array: var myArray = [];for(var i = nl.length; i--; myArray.unshift(nl[i])); // now find the visible (= with offsetWidth more than 0) item: for (i =0; i < myArray.length; i++){ var curEl = myArray[i]; if (curEl.offsetWidth !== 0){ return curEl.getAttribute("class"); } }


Combinando un par de respuestas arriba:

function isVisible (ele) { var style = window.getComputedStyle(ele); return style.width !== "0" && style.height !== "0" && style.opacity !== "0" && style.display!==''none'' && style.visibility!== ''hidden''; }

Como dijo AlexZ, esto puede ser más lento que algunas de tus otras opciones si sabes más específicamente lo que estás buscando, pero esto debería detectar todas las formas principales en que se ocultan los elementos.

Pero, también depende lo que cuente como visible para ti. 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 el contenido de una división se puede hacer del mismo color que el fondo, por lo que no es visible para los usuarios pero aún está representado en la página. O un div se puede mover fuera de la pantalla o esconderse detrás de otros divs, o su contenido puede no ser visible pero el borde sigue siendo visible. Hasta cierto punto, "visible" es un término subjetivo.


De acuerdo con esta documentación de MDN , la propiedad offsetParent un elemento devolverá un null siempre que se oculte, o cualquiera de sus padres, a través de la propiedad de estilo de visualización. Solo asegúrate de que el elemento no sea fijo. Un script para verificar esto, si no tiene una position: fixed; Los elementos en tu página, podrían verse como:

// Where el is the DOM element you''d like to test for visibility function isHidden(el) { return (el.offsetParent === null) }

Por otro lado, si tiene elementos de posición fija que podrían quedar atrapados en esta búsqueda, lamentablemente (y lentamente) tendrá que usar window.getComputedStyle() . La función en ese caso podría ser:

// Where el is the DOM element you''d like to test for visibility function isHidden(el) { var style = window.getComputedStyle(el); return (style.display === ''none'') }

La opción # 2 es probablemente un poco más sencilla ya que cuenta con más casos de borde, pero apuesto a que también es mucho más lenta, así que si tiene que repetir esta operación muchas veces, lo mejor es evitarla.


El código jQuery de http://code.jquery.com/jquery-1.11.1.js tiene un parámetro isHidden

var isHidden = function( elem, el ) { // isHidden might be called from jQuery#filter function; // in that case, element will be second argument elem = el || elem; return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem ); };

Así que parece que hay una verificación adicional relacionada con el documento del propietario

Me pregunto si esto realmente atrapa los siguientes casos:

  1. Elementos ocultos detrás de otros elementos basados ​​en zIndex
  2. Elementos con transparencia total haciéndolos invisibles.
  3. Elementos colocados fuera de la pantalla (es decir, a la izquierda: -1000 px)
  4. Elementos con visibilidad: ocultos.
  5. Elementos con display: ninguno
  6. Elementos sin texto visible o subelementos.
  7. Elementos con altura o anchura establecidos en 0

Entonces lo que encontré es el método más factible:

function visible(elm) { if(!elm.offsetHeight && !elm.offsetWidth) { return false; } if(getComputedStyle(elm).visibility === ''hidden'') { return false; } return true; }

Esto se basa en estos hechos:

  • Una display: none elemento (incluso uno anidado) no tiene ancho ni alto.
  • visiblity está hidden incluso para elementos anidados.

Por lo tanto, no es necesario probar offsetParent o realizar un bucle en el árbol DOM para probar qué padre tiene visibility: hidden . Esto debería funcionar incluso en IE 9.

Podría argumentar si la opacity: 0 y elementos colapsados ​​(tiene un ancho pero no altura, o viceversa) tampoco es realmente visible. Pero, de nuevo, no están por supuesto ocultos.


Esta es una forma de determinarlo para todas las propiedades css, incluida la visibilidad:

html:

<div id="element">div content</div>

css:

#element { visibility:hidden; }

javascript:

var element = document.getElementById(''element''); if(element.style.visibility == ''hidden''){ alert(''hidden''); } else { alert(''visible''); }

Funciona para cualquier propiedad css y es muy versátil y confiable.


Esto devuelve verdadero si y solo si el elemento y todos sus ancestros son visibles. Solo mira las propiedades de display y estilo de visibility :

var isVisible = function(el){ // returns true iff el and all its ancestors are visible return el.style.display !== ''none'' && el.style.visibility !== ''hidden'' && (el.parentElement? isVisible(el.parentElement): true) };


Esto es lo que hice:

HTML y CSS: ocultó el elemento por defecto

<html> <body> <button onclick="myFunction()">Click Me</button> <p id="demo" style ="visibility: hidden;">Hello World</p> </body> </html>

JavaScript: se agregó un código para verificar si la visibilidad está oculta o no:

<script> function myFunction() { if ( document.getElementById("demo").style.visibility === "hidden"){ document.getElementById("demo").style.visibility = "visible"; } else document.getElementById("demo").style.visibility = "hidden"; } </script>


Si el elemento es visible regularmente (pantalla: bloque y visibilidad: visible), pero algún contenedor padre está oculto, entonces podemos usar clientWidth y clientHeight para verificarlo.

function isVisible (ele) { return ele.clientWidth !== 0 && ele.clientHeight !== 0 && ele.style.opacity !== 0 && ele.style.visibility !== ''hidden''; }

Plunker (haga clic aquí)


Si estás interesado en visible por el usuario:

function isVisible(elem) { if (!(elem instanceof Element)) throw Error(''DomUtil: elem is not an element.''); const style = getComputedStyle(elem); if (style.display === ''none'') return false; if (style.visibility !== ''visible'') return false; if (style.opacity < 0.1) return false; if (elem.offsetWidth + elem.offsetHeight + elem.getBoundingClientRect().height + elem.getBoundingClientRect().width === 0) { return false; } const elemCenter = { x: elem.getBoundingClientRect().left + elem.offsetWidth / 2, y: elem.getBoundingClientRect().top + elem.offsetHeight / 2 }; if (elemCenter.x < 0) return false; if (elemCenter.x > (document.documentElement.clientWidth || window.innerWidth)) return false; if (elemCenter.y < 0) return false; if (elemCenter.y > (document.documentElement.clientHeight || window.innerHeight)) return false; let pointContainer = document.elementFromPoint(elemCenter.x, elemCenter.y); do { if (pointContainer === elem) return true; } while (pointContainer = pointContainer.parentNode); return false; }

Probado en (usando terminología de mocha ):

describe.only(''visibility'', function () { let div, visible, notVisible, inViewport, leftOfViewport, rightOfViewport, aboveViewport, belowViewport, notDisplayed, zeroOpacity, zIndex1, zIndex2; before(() => { div = document.createElement(''div''); document.querySelector(''body'').appendChild(div); div.appendChild(visible = document.createElement(''div'')); visible.style = ''border: 1px solid black; margin: 5px; display: inline-block;''; visible.textContent = ''visible''; div.appendChild(inViewport = visible.cloneNode(false)); inViewport.textContent = ''inViewport''; div.appendChild(notDisplayed = visible.cloneNode(false)); notDisplayed.style.display = ''none''; notDisplayed.textContent = ''notDisplayed''; div.appendChild(notVisible = visible.cloneNode(false)); notVisible.style.visibility = ''hidden''; notVisible.textContent = ''notVisible''; div.appendChild(leftOfViewport = visible.cloneNode(false)); leftOfViewport.style.position = ''absolute''; leftOfViewport.style.right = ''100000px''; leftOfViewport.textContent = ''leftOfViewport''; div.appendChild(rightOfViewport = leftOfViewport.cloneNode(false)); rightOfViewport.style.right = ''0''; rightOfViewport.style.left = ''100000px''; rightOfViewport.textContent = ''rightOfViewport''; div.appendChild(aboveViewport = leftOfViewport.cloneNode(false)); aboveViewport.style.right = ''0''; aboveViewport.style.bottom = ''100000px''; aboveViewport.textContent = ''aboveViewport''; div.appendChild(belowViewport = leftOfViewport.cloneNode(false)); belowViewport.style.right = ''0''; belowViewport.style.top = ''100000px''; belowViewport.textContent = ''belowViewport''; div.appendChild(zeroOpacity = visible.cloneNode(false)); zeroOpacity.textContent = ''zeroOpacity''; zeroOpacity.style.opacity = ''0''; div.appendChild(zIndex1 = visible.cloneNode(false)); zIndex1.textContent = ''zIndex1''; zIndex1.style.position = ''absolute''; zIndex1.style.left = zIndex1.style.top = zIndex1.style.width = zIndex1.style.height = ''100px''; zIndex1.style.zIndex = ''1''; div.appendChild(zIndex2 = zIndex1.cloneNode(false)); zIndex2.textContent = ''zIndex2''; zIndex2.style.left = zIndex2.style.top = ''90px''; zIndex2.style.width = zIndex2.style.height = ''120px''; zIndex2.style.backgroundColor = ''red''; zIndex2.style.zIndex = ''2''; }); after(() => { div.parentNode.removeChild(div); }); it(''isVisible = true'', () => { expect(isVisible(div)).to.be.true; expect(isVisible(visible)).to.be.true; expect(isVisible(inViewport)).to.be.true; expect(isVisible(zIndex2)).to.be.true; }); it(''isVisible = false'', () => { expect(isVisible(notDisplayed)).to.be.false; expect(isVisible(notVisible)).to.be.false; expect(isVisible(document.createElement(''div''))).to.be.false; expect(isVisible(zIndex1)).to.be.false; expect(isVisible(zeroOpacity)).to.be.false; expect(isVisible(leftOfViewport)).to.be.false; expect(isVisible(rightOfViewport)).to.be.false; expect(isVisible(aboveViewport)).to.be.false; expect(isVisible(belowViewport)).to.be.false; }); });


Si solo estamos recolectando formas básicas de detectar la visibilidad, no me olvide:

opacity > 0.01; // probably more like .1 to actually be visible, but YMMV

Y en cuanto a cómo obtener atributos:

element.getAttribute(attributename);

Entonces, en tu ejemplo:

document.getElementById(''snDealsPanel'').getAttribute(''visibility'');

Pero qa No funciona aquí. Mire más de cerca y verá que la visibilidad se está actualizando no como un atributo en el elemento, sino utilizando la propiedad de style . Este es uno de los muchos problemas para tratar de hacer lo que estás haciendo. Entre otros: no puede garantizar que haya realmente algo que ver en un elemento, solo porque su visibilidad, pantalla 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 obtener más detalles, una rápida búsqueda en Google revela this , e incluso incluye una biblioteca para intentar resolver el problema. (YMMV)

Echa 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, así que me abstendré de marcar:

(EDITAR: OP DICE QUE ELLA DE LAS PÁGINAS, NO CREARLAS, POR LO TANTO, NO SE APLICA) ¿Una mejor opción? Vincule la visibilidad de los elementos a las propiedades del modelo y siempre haga que la visibilidad dependa de ese modelo, como lo hace Angular con ng-show. Puede hacerlo utilizando cualquier herramienta que desee: Angular, JS simple, lo que sea. Mejor aún, puede cambiar la implementación de 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. Mucho mejor es 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).


Solo para la referencia, se debe tener en cuenta que getBoundingClientRect() puede funcionar en ciertos casos.

Por ejemplo, una simple comprobación de que el elemento está oculto mediante la display: none podría tener este aspecto:

var box = element.getBoundingClientRect(); var visible = box.width && box.height;

Esto también es útil porque también cubre el ancho cero, la altura cero y la position: fixed casos position: fixed . Sin embargo, no debe informar los elementos ocultos con opacity: 0 o visibility: hidden (pero tampoco lo haría offsetParent ).


Tengo una solución más eficaz en comparación con la solución getComputedStyle () de AlexZ cuando uno tiene elementos ''fijos'' de posición, si uno está dispuesto a ignorar algunos casos de borde (ver comentarios):

function isVisible(el) { /* offsetParent would be null if display ''none'' is set. However Chrome, IE and MS Edge returns offsetParent as null for elements with CSS position ''fixed''. So check whether the dimensions are zero. This check would be inaccurate if position is ''fixed'' AND dimensions were intentionally set to zero. But..it is good enough for most cases.*/ if (!el.offsetParent && el.offsetWidth === 0 && el.offsetHeight === 0) { return false; } return true; }

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 en él sin problemas (incluso si la opacidad es 0 o la propiedad de visibilidad de CSS está ''oculta'', etc.).


Todas las otras soluciones se rompieron por alguna situación para mí ..

Ver la respuesta ganadora rompiendo en:

plnkr.co/edit/6CSCA2fe4Gqt4jCBP2wu?p=preview

Finalmente, decidí que la mejor solución era $(elem).is('':visible'') ; sin embargo, esto no es javascript puro. es jquery ..

Así que eché un vistazo a su fuente y encontré lo que quería

jQuery.expr.filters.visible = function( elem ) { return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ); };

Esta es la fuente: https://github.com/jquery/jquery/blob/master/src/css/hiddenVisibleSelectors.js


Una pequeña adición a la respuesta de Ohad Navon.

Si el centro del elemento pertenece al otro elemento, no lo encontraremos.

Así que para asegurarse de que uno de los puntos del elemento se encuentre visible

function isElementVisible(elem) { if (!(elem instanceof Element)) throw Error(''DomUtil: elem is not an element.''); const style = getComputedStyle(elem); if (style.display === ''none'') return false; if (style.visibility !== ''visible'') return false; if (style.opacity === 0) return false; if (elem.offsetWidth + elem.offsetHeight + elem.getBoundingClientRect().height + elem.getBoundingClientRect().width === 0) { return false; } var elementPoints = { ''center'': { x: elem.getBoundingClientRect().left + elem.offsetWidth / 2, y: elem.getBoundingClientRect().top + elem.offsetHeight / 2 }, ''top-left'': { x: elem.getBoundingClientRect().left, y: elem.getBoundingClientRect().top }, ''top-right'': { x: elem.getBoundingClientRect().right, y: elem.getBoundingClientRect().top }, ''bottom-left'': { x: elem.getBoundingClientRect().left, y: elem.getBoundingClientRect().bottom }, ''bottom-right'': { x: elem.getBoundingClientRect().right, y: elem.getBoundingClientRect().bottom } } for(index in elementPoints) { var point = elementPoints[index]; if (point.x < 0) return false; if (point.x > (document.documentElement.clientWidth || window.innerWidth)) return false; if (point.y < 0) return false; if (point.y > (document.documentElement.clientHeight || window.innerHeight)) return false; let pointContainer = document.elementFromPoint(point.x, point.y); if (pointContainer !== null) { do { if (pointContainer === elem) return true; } while (pointContainer = pointContainer.parentNode); } } return false; }


Usa el mismo código que jQuery:

jQuery.expr.pseudos.visible = function( elem ) { return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ); };

Entonces, en una función:

function isVisible(e) { return !!( e.offsetWidth || e.offsetHeight || e.getClientRects().length ); }

Funciona como un encanto en mi Win / IE10, Linux / Firefox.45, Linux / Chrome.52 ...

Muchas gracias a jQuery sin jQuery!


Esto puede ayudar: Oculte el elemento colocándolo en la posición más a la izquierda y luego verifique la propiedad offsetLeft. Si desea utilizar jQuery, simplemente puede marcar el selector :visible y obtener el estado de visibilidad del elemento.

HTML:

<div id="myDiv">Hello</div>

CSS:

<!-- for javaScript--> #myDiv{ position:absolute; left : -2000px; } <!-- for jQuery --> #myDiv{ visibility:hidden; }

javaScript:

var myStyle = document.getElementById("myDiv").offsetLeft; if(myStyle < 0){ alert("Div is hidden!!"); }

jQuery:

if( $("#MyElement").is(":visible") == true ) { alert("Div is hidden!!"); }

jsFiddle