Comprobar si el elemento es visible en DOM

378

¿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?

Hommer Smith
fuente
1
Eso no usa pantalla, usa visibilidad, así que verifique la visibilidad (oculta o visible) por ejemplo:document.getElementById('snDealsPanel').style.visibility
PSL
PSL Si quisiera hacer esto de manera más general, ¿qué atributos debo verificar: visibilidad, visualización ...?
Hommer Smith
Puede hacerlo genérico a su manera, pero lo que estoy diciendo es que usa visibilidad inspeccionando el elemento.
PSL
Aquí está mi código (no jquery) para esta pregunta stackoverflow.com/a/22969337/2274995
Aleko
El enlace está roto, lo que hace que su pregunta no sea fácil de entender. Vuelva a enmarcarlo amablemente.
yogihosting

Respuestas:

619

De acuerdo con esta documentación de MDN , la offsetParentpropiedad de un elemento volverá nullsiempre 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 tiene position: fixed;elementos en su página, podría verse así:

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

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:

// 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 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.

AlexZ
fuente
Wow no es broma. No debería haber ninguna razón para usar el segundo método como una solución universal; ninguna página debería tener elementos fijos que su creador desconozca explícitamente, y uno puede verificarlos manualmente usando el método getComputedStyle () después de ejecutar primero el método offsetParent en todos los elementos.
AlexZ
66
También para su información, acabo de descubrir que el.offsetParentno funcionaba en IE9 para elementos no fijos. O eso parece, de todos modos. (OK para IE11, sin embargo). Así que seguí con getComputedStyledespués de todo.
Nick
1
@AlexZ No estoy seguro si offsetParent realmente hace un reflujo en los navegadores de hoy, pero sí un par de años atrás, solían hacerlo, eso es lo que entiendo de los informes. Tenga en cuenta que jsPerf solo menciona la velocidad de ejecución, mientras que el reflujo se trata de la pantalla. Y los reflujos hacen que la IU sea pobre. Personalmente no iré por la velocidad de una rutina que probablemente se llama 5/6 veces en una página.
Ethan
2
¡Pobre de mí! getComputedStyleno funciona correctamente: plnkr.co/edit/6CSCA2fe4Gqt4jCBP2wu?p=preview Sin embargo, también lo hace offsetParent, ¿quizás debería usarse una combinación de los dos?
Guy Mograbi
2
para ie9 + ie10 puede verificar si offsetParent = body para elementos no visibles.
SuperUberDuper
99

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

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

chico mograbi
fuente
11
Esto regresará truepara un elemento convisibility:hidden
Yuval A.
99
@YuvalA .: Sí, porque el elemento aún es visible. ¡Establecer un elemento para que visibility:hiddenya no muestre contenido, pero aún toma el ancho y la altura del elemento!
Jacob van Lingen
44
@Michael puede navegar fácilmente el código jQuery y si está utilizando cualquier IDE moderno (pruébelo si no) puede saltar a las partes correctas del código mientras usa jQuery o cualquier otra lib. Puede aprender mucho mientras explora bases de código de proyectos de código abierto.
Lukas Liesis
53

Si está 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 moca ):

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;
    });
});
Ohad Navon
fuente
un caso de borde si el elemento se coloca fuera de la ventana gráfica, puede ser atrapado por "if (! pointContainer) return false;" comprobando el primer punto Contenedor
Jerry Deng
Si desea verificar si el usuario podría verlo, ¿tendría que usar un scrollIntoViewderecho? Esto es bastante costoso. ¿Hay otra manera inteligente?
Kim Kern
36

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:

<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 visible!!");        
}

jsFiddle

MD Ashaduzzaman
fuente
12
El OP solicita una respuesta sin jQuery.
Stephen Quan
Fue editado más tarde, supongo. Cuando respondí no fue mencionado en el hilo.
Md. Ashaduzzaman
2
@StephenQuan, he actualizado la respuesta con la solución jQuery y javaScript.
Md. Ashaduzzaman
66
para el ejemplo de jQuery, ¿no debería la alerta decir "Div es visible?"
Andrei Bazanov
No quisiera concluir que un elemento está completamente oculto solo porque su offsetLeft es menor que 0: ¿qué pasa si es solo un pequeño número de píxeles menor que 0 y su parte derecha está visible? (Estoy de acuerdo en que esto parecería un diseño tonto, pero nunca se sabe con los diseñadores web en estos días). Probablemente sea mejor agregar el ancho para compensar Izquierda y ver si el resultado es aún menor que 0. Por si acaso.
Silas S. Brown
31

Use 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!

Yvan
fuente
Agradable, pero no cubre elementos ocultos por desbordamiento.
Alph.Dev
bonito pero que porque !! (doble negación)?
Sunil Garg
3
Para forzar el resultado como booleano. Como e.offsetWidthes un entero, !e.offsetWidthregresará falsesi e.offsetWidthes mayor que cero (el elemento es visible). Por lo tanto, agregar otro !como en !!e.offsetWidthdevolverá truesi e.offsetWidthes mayor que cero. Es una abreviatura para, return e.offsetWidth > 0 ? true : falseo obviamente return e.offsetWidth > 0.
Yvan
16

Combinando un par de respuestas anteriores:

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 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.

Mateo
fuente
1
Agradable, pero style.opacity, style.height y style.width devuelven una cadena para que no funcione! ==
Maslow
Otra forma en que un elemento podría ocultarse a través del estilo es que su color podría coincidir con el color de fondo, o su índice z podría ser más bajo que otros elementos.
nu everest
agregar display:nonea esto sería genial. ¡Una solución de trabajo adecuada!
Gijo Varghese
7

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):

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

Munawwar
fuente
6

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.

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

Plunker (haga clic aquí)

Vlada
fuente
ele.style.visibility !== 'hidden'Es redundante aquí. En ese caso, clientWidth y clientHeight serán 0.
subdavis
5

Si solo estamos recopilando formas básicas de detectar la visibilidad, no me olvides:

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 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 stylepropiedad. 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).

XML
fuente
Estoy analizando sitios, esto no es para mi propio sitio ... :)
Hommer Smith
4

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:

//different results in Chrome and Firefox
console.log(document.querySelector('#hidden1').offsetParent); //null Chrome & Firefox
console.log(document.querySelector('#fixed1').offsetParent); //null in Chrome, not null in Firefox
    <div id="hidden1" style="display:none;"></div>
    <div id="fixed1" style="position:fixed;"></div>

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:

var child1 = document.querySelector('#child1');
console.log(getComputedStyle(child1).display);
//child will show "block" instead of "none"
<div id="parent1" style="display:none;">
  <div id="child1" style="display:block"></div>
</div>

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:

console.log(document.querySelector('#div1').clientHeight); //not zero
console.log(document.querySelector('#span1').clientHeight); //zero
<div id="div1">test1 div</div>
<span id="span1">test2 span</span>

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.

console.log(document.querySelector('#notvisible1').getClientRects().length);
console.log(document.querySelector('#notvisible1').clientHeight);
console.log(document.querySelector('#notvisible2').getClientRects().length);
console.log(document.querySelector('#notvisible2').clientHeight);
console.log(document.querySelector('#notvisible3').getClientRects().length);
console.log(document.querySelector('#notvisible3').clientHeight);
<div id="notvisible1" style="height:0; overflow:hidden; background-color:red;">not visible 1</div>

<div id="notvisible2" style="visibility:hidden; background-color:yellow;">not visible 2</div>

<div id="notvisible3" style="opacity:0; background-color:blue;">not visible 3</div>

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.

crisc82
fuente
3

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: nonepodría verse algo así:

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

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

encarnar
fuente
La mejor respuesta para mí ... simple y efectiva. ¡Y ningún voto a favor después de 3 años! Continúa mostrando el valor de la "sabiduría de la multitud". Mi versión: var isVisible = el => (r => r.width && r.height)(el.getBoundingClientRect());. Entonces puedo filtrar conjuntos de elementos de la siguiente manera: $$(sel).filter(isVisible).
7vujy0f0hy
Me parece la solución más simple developer.mozilla.org/en-US/docs/Web/API/Element/…
Marian07 01 de
Esto no funciona cuando es visible para el usuario ... si se desplaza hacia afuera, seguirá siendo cierto
Ray Foss
3

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:

  • Un display: noneelemento (incluso uno anidado) no tiene ancho ni alto.
  • visiblityes hiddenincluso para elementos anidados.

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

Podría argumentar si los opacity: 0elementos colapsados ​​(tiene un ancho pero no alto, o viceversa) tampoco son realmente visibles. Pero, de nuevo, no están ocultos.

Tokimon
fuente
3

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

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;
}
Guy Messika
fuente
3

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:

private isVisible(elem) {
    const style = getComputedStyle(elem);

    if (style.display === 'none') return false;
    if (style.visibility !== 'visible') return false;
    if ((style.opacity as any) === 0) return false;

    if (
        elem.offsetWidth +
        elem.offsetHeight +
        elem.getBoundingClientRect().height +
        elem.getBoundingClientRect().width === 0
    ) return false;

    const elementPoints = {
        center: {
            x: elem.getBoundingClientRect().left + elem.offsetWidth / 2,
            y: elem.getBoundingClientRect().top + elem.offsetHeight / 2,
        },
        topLeft: {
            x: elem.getBoundingClientRect().left,
            y: elem.getBoundingClientRect().top,
        },
        topRight: {
            x: elem.getBoundingClientRect().right,
            y: elem.getBoundingClientRect().top,
        },
        bottomLeft: {
            x: elem.getBoundingClientRect().left,
            y: elem.getBoundingClientRect().bottom,
        },
        bottomRight: {
            x: elem.getBoundingClientRect().right,
            y: elem.getBoundingClientRect().bottom,
        },
    };

    const docWidth = document.documentElement.clientWidth || window.innerWidth;
    const docHeight = document.documentElement.clientHeight || window.innerHeight;

    if (elementPoints.topLeft.x > docWidth) return false;
    if (elementPoints.topLeft.y > docHeight) return false;
    if (elementPoints.bottomRight.x < 0) return false;
    if (elementPoints.bottomRight.y < 0) return false;

    for (let index in elementPoints) {
        const point = elementPoints[index];
        let pointContainer = document.elementFromPoint(point.x, point.y);
        if (pointContainer !== null) {
            do {
                if (pointContainer === elem) return true;
            } while (pointContainer = pointContainer.parentNode);
        }
    }
    return false;
}
Israel
fuente
2

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 );
};

Parece que hay un control adicional relacionado 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 completa haciéndolos invisibles
  3. Elementos posicionados fuera de la pantalla (es decir, a la izquierda: -1000 px)
  4. Elementos con visibilidad: ocultos
  5. Elementos con pantalla: ninguno
  6. Elementos sin texto visible o subelementos
  7. Elementos con altura o ancho establecidos en 0
Scott Izu
fuente
0

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:

  // 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");
    }
  }
no especificado
fuente
0

Esto es lo que hice:

HTML y CSS: hizo el elemento oculto 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>
Ajas Jansher
fuente
-1

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.

William Green
fuente