Truco Manso: saber si un elemento es visible con jquery

Muchas veces es imprescindible saber si un elemento es o no visible. Con jQuery averiguarlo es bastante fácil, símplemente hay que preguntar si el filtro “visible” está presente (también se puede mirar ‘hidden‘). Sin embargo hay que tener en cuenta un par de cosas, porque puede ser que jQuery no nos esté diciendo lo que queremos saber en realidad.

El problema viene cuando preguntamos por el div X y el padre está oculto, entonces jQuery nos dirá que X no está oculto, pero realmente el usuario no lo estará viendo en la pantalla, por lo que sí estará oculto.

Como siempre, lo mejor son los ejemplos.

Ejemplo 1:

Empecemos por el principio. Si yo tengo el siguiente código HTML:

<div id="DivBlock">Element</div>

Al ejecutar el siguiente código, tendremos dos alerts, el primero diciendo “Visible!” y el segundo “Not Hidden”.

if ($('#DivBlock').is (':visible')) alert ("Visible!");
if (!$('#DivBlock').is (':hidden')) alert ("Not Hidden");

Como veis, hasta aquí todo funciona a la perfección, y podeis ver que preguntar si un objeto está visible o oculto en jquery no tiene demasiada dificultad.

Ejemplo 2:

Ahora bien, veamos que ocurre si el padre está oculto:

  <div style="display: none;">
   <div id="DivBlock">Element</div>
  </div>

Ahora si ejecutamos el siguiente código, en todos los navegadores menos Safari volverán a saltar los alerts, y sin embargo el elemento está oculto!!.

if ($('#DivBlock').is (':visible')) alert ("Visible!");
if (!$('#DivBlock').is (':hidden')) alert ("Not Hidden");

Oh my god! ¡¡jQuery lo está haciendo mal!!

Afortunadamente, la solución a este problema es muy sencilla. Para preguntar si el elemento X es realmente visible, hay que preguntar ¿son X y todos sus padres visibles?, o lo que es lo mismo ¿es X visible y ningún padre de X ha sido ocultado? que en jQuery viene a expresarse de la siguiente manera:

if ($('#DivBlock').is (':visible') && $('#DivBlock').parents (':hidden').length == 0)
  alert ("Visible!");

Finalmente, como solución alternativa, se puede crear un selector para preguntarle directamente:

jQuery.extend(
  jQuery.expr[ ":" ], 
  { reallyvisible : "(jQuery(a).is(':visible') && jQuery(a).parents(':hidden').length == 0)" }
);

Con lo que el código javascript del ejemplo anterior quedaría:

if ($('#DivBlock').is (':reallyvisible'))  alert ("Visible!");

Para más información:

Trackback URL

12 Comments on "Truco Manso: saber si un elemento es visible con jquery"

  1. adrive
    03/06/2009 at 1:02 pm Permalink

    Great job! Your :reallyvisible selector should definitely be in the core!

  2. Jiri Melcak
    05/08/2009 at 12:16 pm Permalink

    Thanks very much. Help me a lot this evening.

  3. Aamir Afridi
    21/08/2009 at 7:27 am Permalink

    Awesome man… Very very helpful…

  4. Ian Holmes
    09/09/2009 at 1:01 am Permalink

    Thanks for the article – well explained and eay to follow. However, the syntax for your extension to the jQuery selector engine does not work – try this instead:

    jQuery.extend(jQuery.expr[":"],{reallyvisible: function(a) { return (jQuery(a).is(‘:visible’) && jQuery(a).parents(‘:hidden’).length == 0) }});

  5. Carlos
    10/11/2009 at 2:11 pm Permalink

    if (!$(‘#DivBlock’).is (‘:hidden’)) alert (“Not Hidden”);

    not work with IE8.

  6. total 13
    30/04/2010 at 12:09 am Permalink

    Pues a mi el is(:visible) si me esta funcionando como debería, (me devuelve false si algun padre esta oculto), que encima es el comportamiento que no quiero jaja, (aunque sea el esperable y razonable). Con Firefox 3.6.3 y jquery 1.3.2 (salió el 19 de Febrero de 2009, un mes después de este artículo así que quizás lo hayan solucionado).

    Saludos!

  7. Jose T.
    21/10/2010 at 7:22 pm Permalink

    Excelente amigo, me sacaste de un apuro.

  8. Abraham
    09/12/2010 at 2:23 pm Permalink

    Me sirvió un rato el dato pero, efectivamente, desde la versión 1.3.2 ya tienen ese cambio y lo tengo comprobado. Aquí está la info http://docs.jquery.com/Release:jQuery_1.3.2#:visible.2F:hidden_Overhauled
    Saludos!

  9. Pau Sanchez
    06/01/2011 at 3:18 pm Permalink

    @Jose T. y @Abraham gracias por vuestro comentario

  10. Luis
    18/04/2012 at 8:57 pm Permalink

    Excelente amigo! muchas gracias

  11. Andres Misiak
    29/06/2012 at 6:07 am Permalink

    Gracias por la nota, me sirvió mucho.

  12. Alejandro
    14/03/2014 at 4:14 pm Permalink

    Muchísimas Gracias!!

Hi Stranger, leave a comment:

ALLOWED XHTML TAGS:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Subscribe to Comments