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

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

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

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

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

还有我可能漏掉的吗?


当前回答

const isVisible = (selector) => { let selectedElement let topElement let selectedData selectedElement = document.querySelector(selector) if (!selectedElement) { return false } selectedData = selectedElement.getBoundingClientRect() if (!selectedData || !Object.keys(selectedData)) { return false } if (!(selectedData.width > 0) || !(selectedData.height > 0)) { return false } topElement = document.elementFromPoint(selectedData.top, selectedData.left) if (selectedElement !== topElement) { return false } return true } const output = document.querySelector('.text') output.innerHTML = '.x element is visible: ' + isVisible('.x') .block { width: 100px; height: 100px; background: black; } .y { background: red; margin-top: -100px; } <div class="text"></div> <div class="x block"></div> <div class="y block"></div>

其他回答

这是对奥哈德·纳冯的回答的一点补充。

如果元素的中心属于另一个元素,我们就找不到它。

为了确保元素的其中一个点是可见的

function isElementVisible(elem) {
    if (!(elem instanceof Element)) throw Error('DomUtil: elem is not an element.');
    const style = getComputedStyle(elem);
    if (style.display === 'none') return false;
    if (style.visibility !== 'visible') return false;
    if (style.opacity === 0) return false;
    if (elem.offsetWidth + elem.offsetHeight + elem.getBoundingClientRect().height +
        elem.getBoundingClientRect().width === 0) {
        return false;
    }
    var elementPoints = {
        'center': {
            x: elem.getBoundingClientRect().left + elem.offsetWidth / 2,
            y: elem.getBoundingClientRect().top + elem.offsetHeight / 2
        },
        'top-left': {
            x: elem.getBoundingClientRect().left,
            y: elem.getBoundingClientRect().top
        },
        'top-right': {
            x: elem.getBoundingClientRect().right,
            y: elem.getBoundingClientRect().top
        },
        'bottom-left': {
            x: elem.getBoundingClientRect().left,
            y: elem.getBoundingClientRect().bottom
        },
        'bottom-right': {
            x: elem.getBoundingClientRect().right,
            y: elem.getBoundingClientRect().bottom
        }
    }

    for(index in elementPoints) {
        var point = elementPoints[index];
        if (point.x < 0) return false;
        if (point.x > (document.documentElement.clientWidth || window.innerWidth)) return false;
        if (point.y < 0) return false;
        if (point.y > (document.documentElement.clientHeight || window.innerHeight)) return false;
        let pointContainer = document.elementFromPoint(point.x, point.y);
        if (pointContainer !== null) {
            do {
                if (pointContainer === elem) return true;
            } while (pointContainer = pointContainer.parentNode);
        }
    }
    return false;
}

如果元素是常规可见的(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);
}

活塞(点击这里)

let element = document.getElementById('element');
let rect = element.getBoundingClientRect();

if(rect.top == 0 && 
  rect.bottom == 0 && 
  rect.left == 0 && 
  rect.right == 0 && 
  rect.width == 0 && 
  rect.height == 0 && 
  rect.x == 0 && 
  rect.y == 0)
{
  alert('hidden');
}
else
{
  alert('visible');
}

所以我找到了最可行的方法:

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

这是基于以下事实:

显示:所有元素(即使是嵌套的元素)都没有宽度和高度。 可见性即使对于嵌套的元素也是隐藏的。

因此不需要测试offsetParent或在DOM树中循环来测试哪个父对象具有可见性:hidden。这应该可以在ie9中工作。

你可能会说,如果透明度:0和折叠的元素(有宽度但没有高度-反之亦然)也不是真正可见的。但话说回来,它们并不是隐藏的。

根据MDN文档,元素的offsetParent属性将在它或它的任何父元素通过display style属性被隐藏时返回null。只要确保元素不是固定的。一个脚本来检查这个,如果你没有位置:fixed;页面上的元素可能是这样的:

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

另一方面,如果您确实有位置固定的元素可能会在此搜索中被捕获,那么您将不得不遗憾地(并且缓慢地)使用window.getComputedStyle()。这种情况下的函数可能是:

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

选项2可能更简单一点,因为它考虑了更多的边缘情况,但我打赌它也会慢很多,所以如果你不得不多次重复这个操作,最好避免它。