Get only visible element using pure javascript

后端 未结 6 566
Happy的楠姐
Happy的楠姐 2020-12-10 15:03

I have elements like below

send Message
send Message
sen
相关标签:
6条回答
  • 2020-12-10 15:45
    var $el = document.querySelectorAll('.one');
    var visibleElements;
    
    for (var i = 0; i < $el.length; i++) {
        var currentElement = $el[i];
        var $style = window.getComputedStyle(currentElement, null);
    
        if (!currentElement) {
            return false;
        } else if (!$style) {
            return false;
        } else if ($style.display === 'none') {
            return false;
        } else {
            visibleElements.push(currentElement);
        }
    }
    

    First we get all the elements using document querySelectorAll. Then, we need to iterate over all the elements. To get the style, use getComputedStyle.

    After that :visible check only for display and we do it the same way.

    A more comprehensive approach:

    function isVisible(el) {
            while (el) {
                if (el === document) {
                    return true;
                }
    
                var $style = window.getComputedStyle(el, null);
    
                if (!el) {
                    return false;
                } else if (!$style) {
                    return false;
                } else if ($style.display === 'none') {
                    return false;
                } else if ($style.visibility === 'hidden') {
                    return false;
                } else if (+$style.opacity === 0) {
                    return false;
                } else if (($style.display === 'block' || $style.display === 'inline-block') &&
                    $style.height === '0px' && $style.overflow === 'hidden') {
                    return false;
                } else {
                    return $style.position === 'fixed' || isVisible(el.parentNode);
                }
            }
        }
    

    This would check for any possible way an element could be visible in the dom to my knowledge minus the z-index cases.

    0 讨论(0)
  • 2020-12-10 15:48

    So all jQuery's :visible selector does is check the display property. If that's all you want, this is all you'd need.

    (window.getComputedStyle(el).getPropertyValue('display') !== 'none')
    

    However, this is lacking in many use cases. If you seek a more comprehensive solution, keep reading.

    Both Element.getBoundingClientRect() and window.getComputedStyle() are useful for determining if the element is visible and in the viewport.

    You can't use getBoundingRect() alone to determine the visibility, and while you could use getComputedStyle() solely, it's not the optimal solution in terms of performance.

    Both of these functions used in conjunction with each other is the best option (around 22% faster than getComputedStyle() alone.

    function inViewport(els) {
        let matches = [],
            elCt = els.length;
    
        for (let i=0; i<elCt; ++i) {
            let el = els[i],
                b = el.getBoundingClientRect(), c;
    
            if  (b.width > 0 && b.height > 0 &&
                b.left+b.width > 0 && b.right-b.width < window.outerWidth && 
                b.top+b.height > 0 && b.bottom-b.width < window.outerHeight && 
                (c = window.getComputedStyle(el)) &&
                c.getPropertyValue('visibility') === 'visible' &&
                c.getPropertyValue('opacity') !== 'none') {
                matches.push(el);
            }
        }
        return matches;
    }
    

    With a usage example of...

    var els = document.querySelectorAll('.one'),
        visibleEls = inViewport(els);
    

    This ensures that the display is not set to "none", the visibility is "visible", the width and height are greater than 0, and the element is within the bounds of the viewport.

    0 讨论(0)
  • 2020-12-10 15:49

    Here's something you can use, pure Javascript:

    // Get all elements on the page (change this to another DOM element if you want)
    var all = document.getElementsByTagName("*");
    
    for (var i = 0, max = all.length; i < max; i++) {
        if (isHidden(all[i]))
            // hidden
        else 
            // visible
    }
    
    function isHidden(el) {
        var style = window.getComputedStyle(el);
        return ((style.display === 'none') || (style.visibility === 'hidden'))
    }
    
    0 讨论(0)
  • 2020-12-10 15:52

    I have something shorter:

    Array.from(document.querySelectorAll('.one')).filter(s =>
       window.getComputedStyle(s).getPropertyValue('display') != 'none'
    );
    

    Returns all elements with attribute display block set.

    0 讨论(0)
  • 2020-12-10 15:52

    If you're using the hidden attribute :

    document.querySelector(".one:not([hidden])");
    
    0 讨论(0)
  • 2020-12-10 16:06

    Use getBoundingClientRect. It will return height and width of zero if the element is not in the DOM, or is not displayed.

    Note that this cannot be used to determine if an element is not visible due to visibility: hidden or opacity: 0. AFAIK this behavior is identical to the jQuery :visible "selector". Apparently jQuery uses offsetHeight and offsetWidth of zero to check for non-visibility.

    This solution will also not check if the item is not visible due to being off the screen (although you could check that easily enough), or if the element is hidden behind some other element.

    See also Detect if an element is visible (without using jquery)

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