Check if element is visible in DOM

后端 未结 18 1685

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

相关标签:
18条回答
  • 2020-11-22 07:50

    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)

    0 讨论(0)
  • 2020-11-22 07:50

    So what I found is the most feasible method:

    function visible(elm) {
      if(!elm.offsetHeight && !elm.offsetWidth) { return false; }
      if(getComputedStyle(elm).visibility === 'hidden') { return false; }
      return true;
    }
    

    This is build on these facts:

    • A display: none element (even a nested one) doesn't have a width nor height.
    • visiblity is hidden even for nested elements.

    So no need for testing offsetParent or looping up in the DOM tree to test which parent has visibility: hidden. This should work even in IE 9.

    You could argue if opacity: 0 and collapsed elements (has a width but no height - or visa versa) is not really visible either. But then again they are not per say hidden.

    0 讨论(0)
  • 2020-11-22 07:51

    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.

    0 讨论(0)
  • 2020-11-22 07:51

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

    0 讨论(0)
  • 2020-11-22 07:52

    Improving on @Guy Messika's answer above, breaking and returning false if the center point' X is < 0 is wrong as the element right side may go into the view. here's a fix:

    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;
    }
    
    0 讨论(0)
  • 2020-11-22 08:02

    This may help : Hide the element by positioning it on far most left position and then check the offsetLeft property. If you want to use jQuery you can simply check the :visible selector and get the visibility state of the element.

    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

    0 讨论(0)
提交回复
热议问题