使用纯javascript只获取可见元素

时间:2017-06-18 05:53:04

标签: javascript

我有以下元素

<div class="one">send Message</div>

<div class="one">send Message</div>

<div class="one">send Message</div>

我有一个网页,其中有上面的发送消息按钮,其中一次只能看到一个按钮。其他两个按钮通过一些javascript代码隐藏。例如,如果第二个按钮可见,我应该是能够只得到那个元素。

所以我的代码就像

document.querySelector(".one:visible");

在jquery中,代码是$(".one:visible");,它工作正常,但我需要知道如何通过纯JavaScript进行此操作。

6 个答案:

答案 0 :(得分:3)

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

首先,我们使用文档querySelectorAll获取所有元素。然后,我们需要迭代所有元素。要获得样式,请使用getComputedStyle。

之后:仅显示可见的检查,我们以同样的方式进行检查。

更全面的方法:

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

根据我的知识减去z-index案例,这将检查元素在dom中可见的任何可能方式。

答案 1 :(得分:3)

使用getBoundingClientRect。如果元素不在DOM中,或者不显示,它将返回高度和宽度为零。

请注意,由于visibility: hiddenopacity: 0,这不能用于确定元素是否不可见。 AFAIK此行为与jQuery :visible“selector”相同。显然,jQuery使用零offsetHeightoffsetWidth来检查不可见性。

此解决方案也不会检查项目是否因为不在屏幕外而可见(尽管您可以很容易地检查),或者该元素是否隐藏在其他元素后面。

另见Detect if an element is visible (without using jquery)

答案 2 :(得分:2)

这是你可以使用的东西,纯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'))
}

答案 3 :(得分:1)

If you're using the hidden attribute :

document.querySelector(".one:not([hidden])");

答案 4 :(得分:1)

我有一些短的东西:

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

返回设置了属性display block的所有元素。

答案 5 :(得分:0)

因此jQuery的:visible选择器所做的只是检查display属性。 如果这就是您想要的,那就是您所需要的。

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

但是,在许多用例中都缺少这种方法。如果您寻求更全面的解决方案,请继续阅读。

Element.getBoundingClientRect()window.getComputedStyle()都可用于确定元素是否可见以及在视口中。

您不能单独使用getBoundingRect()来确定可见性,并且虽然可以单独使用getComputedStyle(),但从性能上看,它并不是最佳解决方案。

将这两个函数结合使用是最好的选择(比单独使用getComputedStyle()快22%。

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

以...的用法示例

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

这确保显示不设置为“ none”,可见性为“ visible”,宽度和高度大于0,并且元素在视口范围之内。