views:

297

answers:

3

What is the best way to find if a DOM object is visible?

Various cases when object is considered not visible:

  1. display: none;
  2. visibility: hidden;
  3. one of the parents has display: none or visibility: hidden
  4. Another DOM element is obscuring the queried element (Nice to have, but I can manage without it).
  5. Item outside of screen boundaries.
+2  A: 

Stolen from http://snippets.dzone.com/posts/show/5757:

function isVisible(obj)
{
    if (obj == document) return true

    if (!obj) return false
    if (!obj.parentNode) return false
    if (obj.style) {
        if (obj.style.display == 'none') return false
        if (obj.style.visibility == 'hidden') return false
    }

    //Try the computed style in a standard way
    if (window.getComputedStyle) {
        var style = window.getComputedStyle(obj, "")
        if (style.display == 'none') return false
        if (style.visibility == 'hidden') return false
    }

    //Or get the computed style using IE's silly proprietary way
    var style = obj.currentStyle
    if (style) {
        if (style['display'] == 'none') return false
        if (style['visibility'] == 'hidden') return false
    }

    return isVisible(obj.parentNode)
}
Luca Matteis
Will have to add point 4 and 5 to this script.
Itay Moav
+1  A: 

since its mootools and this got dealt with on the mootools mail list and it is now going to be a part of Element.shortcuts...

/*
* Inspired from http://github.com/jeresig/sizzle/commit/7631f9c3f85e5fa72ac51532399cb593c2cdc71f
* and this http://github.com/jeresig/sizzle/commit/5716360040a440041da19823964f96d025ca734b
* and then http://dev.jquery.com/ticket/4512
*/

Element.implement({

  isHidden: function(){
    var w = this.offsetWidth, h = this.offsetHeight,
    force = (this.tagName === 'TR');
    return (w===0 && h===0 && !force) ? true : (w!==0 && h!==0 && !force) ? false : this.getStyle('display') === 'none';
  },

  isVisible: function(){
    return !this.isHidden();
  }

});

http://gist.github.com/137880

Dimitar Christoff
A: 

Looks like the isVisible method given above was included in the mootools more Element.Shortcuts.

However neither of these methods account for the scroll state of the browser. The following method seems to work pretty well for me for fulfilling requirement #5 stated in the original question.

Element.implement({
isFullyVisible: function() {
    if(this.isVisible()) {
        var coord = this.getCoordinates(),
            winScroll = window.getScroll();

        return winScroll.y <= coord.top;
    } else {
        return false;
    }
}
});
iloveitaly