Monday, July 12, 2010

Check if an element is truly hidden with jQuery

I’m tinkering with a web application and have a situation where I want to select only elements which are visible on the page. Initially I tried using the is(“:visible”) jQuery (v1.4.2) selector, but it seems to be broken, at least for IE.

My solution was inspired by an old posting, and I created the following extension which checks the styles on the current element, and if it’s inherited, then check the parent element.

$.extend(
$.expr[":"],
{
reallyhidden: function (a) {
var obj = $(a);
while ((obj.css("visibility") == "inherit" && obj.css("display") != "none") && obj.parent()) {
obj = obj.parent();
}
return (obj.css("visibility") == "hidden" || obj.css('display') == 'none');
}
}
);

and use it like this:

if (element.is(':reallyhidden')) return false;

7 comments:

  1. thanks for the nice idea on this nice post mikael. what version of IE you thought it's broken?

    .is(":hidden") appears to work fine for me here http://www.rnel.net/code-snippets/jquery/check-if-an-element-is-hidden

    ReplyDelete
  2. I'm using IE8, and have tested it in compatibility mode as well. I'm parsing Japanese pages and making a selection UI, and in IE it would select elements which are hidden.

    The problem seems to be with IE and inherited hidden elements. While Chorme and FF will report the style as "hidden", IE says "inherit", and ":hidden" seems not to check what "inherit" actually is.

    ReplyDelete
  3. Yep thanks for the detailed explanation. Somehow I can picture myself on the equation and your code is truly a great solution.

    I was just wondering, maybe you can just use display:none; on your selection UI instead of visibility:hidden; and then it will work on IE as well.

    from the jQuery document it says;
    "Elements with visibility: hidden or opacity: 0 are considered to be visible, since they still consume space in the layout."
    http://api.jquery.com/hidden-selector

    thanks again

    ReplyDelete
  4. I'm actually creating a GUI where I parse html from arbitrary sources, so I have no control over the styles. And as you say, the docs state that visibility:hidden is not considered the element to actually be hidden (which I missed).

    In my case I need to treat elements which are not visible to the user as hidden.

    ReplyDelete
  5. you can just use $(element).is(":visible")

    ReplyDelete
  6. Kevin, did you read the first line of the post? The whole post is about .is(":visible") not working in IE at the time I wrote the post. Read thru the other comments for an explanation.

    ReplyDelete
  7. Your solution is really good as the visible and hidden doesn't work when visibility=hidden is used to hide the element. I faced this situation and after sometime got the solution as well. So thought of sharing with you.

    http://jquerybyexample.blogspot.in/2012/02/how-to-check-element-visible-or-hidden.html

    ReplyDelete