Check if element is visible in DOM

2018-12-31 14:31发布

Is there any way that I can check if an element is visible in pure JS (no jQuery) ?

So, for example, in this page: Performance Bikes, if you hover over Deals (on the top menu), a window of deals appear, but at the beginning it was not shown. It is in the HTML but it is not visible.

So, given a DOM element, how can I check if it is visible or not? I tried:

window.getComputedStyle(my_element)['display']);

but it doesn't seem to be working. I wonder which attributes should I check. It comes to my mind:

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

Any others that I might be missing?

17条回答
墨雨无痕
2楼-- · 2018-12-31 14:38

If element is regular visible (display:block and visibillity:visible), but some parent container is hidden, then we can use clientWidth and clientHeight for check that.

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

Plunker (click here)

查看更多
旧人旧事旧时光
3楼-- · 2018-12-31 14:39

Use the same code as jQuery does:

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

So, in a function:

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

Works like a charm in my Win/IE10, Linux/Firefox.45, Linux/Chrome.52...

Many thanks to jQuery without jQuery!

查看更多
路过你的时光
4楼-- · 2018-12-31 14:41

According to this MDN documentation, an element's offsetParent property will return null whenever it, or any of its parents, is hidden via the display style property. Just make sure that the element isn't fixed. A script to check this, if you have no position: fixed; elements on your page, might look like:

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

On the other hand, if you do have position fixed elements that might get caught in this search, you will sadly (and slowly) have to use window.getComputedStyle(). The function in that case might be:

// 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')
}

Option #2 is probably a little more straightforward since it accounts for more edge cases, but I bet its a good deal slower, too, so if you have to repeat this operation many times, best to probably avoid it.

查看更多
听够珍惜
5楼-- · 2018-12-31 14:41

The jQuery code from http://code.jquery.com/jquery-1.11.1.js has an isHidden param

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

So it looks like there is an extra check related to the owner document

I wonder if this really catches the following cases:

  1. Elements hidden behind other elements based on zIndex
  2. Elements with transparency full making them invisible
  3. Elements positioned off screen (ie left: -1000px)
  4. Elements with visibility:hidden
  5. Elements with display:none
  6. Elements with no visible text or sub elements
  7. Elements with height or width set to 0
查看更多
长期被迫恋爱
6楼-- · 2018-12-31 14:47

This is a way to determine it for all css properties including visibility:

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

It works for any css property and is very versatile and reliable.

查看更多
旧时光的记忆
7楼-- · 2018-12-31 14:48

I've got a more performant solution compared to AlexZ's getComputedStyle() solution when one has position 'fixed' elements, if one is willing to ignore some edge cases (check comments):

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

Side note: Strictly speaking, "visibility" needs to be defined first. In my case, I am considering an element visible as long as I can run all DOM methods/properties on it without problems (even if opacity is 0 or CSS visibility property is 'hidden' etc).

查看更多
登录 后发表回答