有什么方法,我可以检查如果一个元素是可见的纯JS(没有jQuery) ?

因此,给定一个DOM元素,我如何检查它是否可见?我试着:

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

但这似乎并不奏效。我想知道我应该检查哪些属性。我想到了:

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

还有我可能漏掉的吗?


当前回答

使用与jQuery相同的代码:

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

在函数中:

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

在我的Win/IE10、Linux/Firefox中工作得很好。45岁的Linux / Chrome.52……

感谢没有jQuery的jQuery!

其他回答

结合上面的几个答案:

function isVisible (ele) {
    var style = window.getComputedStyle(ele);
    return  style.width !== "0" &&
    style.height !== "0" &&
    style.opacity !== "0" &&
    style.display!=='none' &&
    style.visibility!== 'hidden';
}

就像AlexZ说的,这可能会比你的一些其他选择更慢,如果你更具体地知道你在寻找什么,但这应该抓住所有隐藏元素的主要方式。

但是,这也取决于你认为什么是可见的。例如,一个div的高度可以设置为0px,但内容仍然可见,这取决于溢出属性。或者,可以将div的内容设置为与背景相同的颜色,这样用户就不会看到它,但仍然可以在页面上显示。或者一个div可以移出屏幕或隐藏在其他div后面,或者它的内容可以是不可见的,但边界仍然可见。在一定程度上,“可见”是一个主观术语。

如果元素是常规可见的(display:block和visibility:visible),但有些父容器是隐藏的,那么我们可以使用clientWidth和clienttheight来检查。

function isVisible (ele) {
  return  ele.clientWidth !== 0 &&
    ele.clientHeight !== 0 &&
    (ele.style.opacity !== '' ? parseFloat(ele.style.opacity) > 0 : true);
}

活塞(点击这里)

如果你正在抓取网站,一个非常低效的方法对我来说是突出显示任何元素,然后截图,然后检查截图是否发生了变化。

//Screenshot

function makeSelected(element){
    let range = new Range()
    range.selectNode(element)
    let selection = window.getSelection()
    selection.removeAllRanges()
    selection.addRange(range)
}
// screenshot again and check for diff

我有一个更有效的解决方案相比AlexZ的getComputedStyle()解决方案时,有位置“固定”元素,如果一个愿意忽略一些边缘情况(检查评论):

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.*/
    return Boolean(el.offsetParent || el.offsetWidth || el.offsetHeight);
}

附注:严格来说,“可见性”首先需要定义。在我的情况下,我正在考虑一个元素可见,只要我可以运行所有DOM方法/属性上没有问题(即使不透明度为0或CSS可见性属性是“隐藏”等)。

对我来说,所有其他的解决方案在某些情况下都失效了。

获胜的答案如下:

http://plnkr.co/edit/6CSCA2fe4Gqt4jCBP2wu?p=preview

最终,我认为最好的解决方案是$(elem).is(':visible')——然而,这不是纯javascript。它是jquery..

所以我偷看了他们的来源,找到了我想要的

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

这是来源:https://github.com/jquery/jquery/blob/master/src/css/hiddenVisibleSelectors.js