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

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

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

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

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

还有我可能漏掉的吗?


当前回答

下面是一个(纯纯的JS)函数,它执行大量的检查,确保给定的元素对用户可见:

function isVisible(element) {
    // Check if the element is null or undefined
    if (!element) return false;

    // Get the element's bounding client rect
    const boundingRect = element.getBoundingClientRect();

    // Check if the element has a positive width and height
    if (boundingRect.width <= 0 || boundingRect.height <= 0) return false;

    // Check if the element's top and left values are within the viewport
    const top = boundingRect.top;
    const left = boundingRect.left;
    const viewportWidth = window.innerWidth || document.documentElement.clientWidth;
    const viewportHeight = window.innerHeight || document.documentElement.clientHeight;
    if (top > viewportHeight || left > viewportWidth) return false;

    // Check if the element's right and bottom values are within the viewport
    const right = boundingRect.right;
    const bottom = boundingRect.bottom;
    if (right < 0 || bottom < 0) return false;

    // Check if the element is hidden by the overflow property
    const parentNode = element.parentNode;
    if (parentNode && getComputedStyle(parentNode).overflow === 'hidden') {
        const parentRect = parentNode.getBoundingClientRect();
        if (top < parentRect.top || bottom > parentRect.bottom || left < parentRect.left || right > parentRect.right) {
            return false;
        }
    }

    const elementComputedStyle = getComputedStyle(element);

    // Check if the element has a z-index of less than 0
    const zIndex = elementComputedStyle.zIndex;
    if (zIndex < 0) return false;

    // Check if the element has a display value of 'none' or an opacity of 0
    const display = elementComputedStyle.display;
    const opacity = elementComputedStyle.opacity;
    if (display === 'none' || opacity === '0') return false;

    // Check if the element is hidden by an ancestor element with a display value of 'none' or an opacity of 0
    let ancestorElement = element.parentElement;
    while (ancestorElement) {
        const ancestorComputedStyle = getComputedStyle(ancestorElement);
        const ancestorDisplay = ancestorComputedStyle.display;
        const ancestorOpacity = ancestorComputedStyle.opacity;
        if (ancestorDisplay === 'none' || ancestorOpacity === '0') return false;
        ancestorElement = ancestorElement.parentElement;
    }

    // Initialize a variable to keep track of whether the element is obscured by another element
    let obscured = false;

    // Check if the element is obscured by another element according to its position
    if (elementComputedStyle.position === 'absolute' || elementComputedStyle.position === 'fixed' ||
        elementComputedStyle.position === 'relative' || elementComputedStyle.position === 'sticky' ||
        elementComputedStyle.position === 'static') {
        let siblingElement = element.nextElementSibling;
        while (siblingElement) {
            if (siblingElement.getBoundingClientRect().top > boundingRect.bottom || siblingElement.getBoundingClientRect().left > boundingRect.right) {
                break;
            }
            if (siblingElement.getBoundingClientRect().bottom > boundingRect.top && siblingElement.getBoundingClientRect().right > boundingRect.left) {
                obscured = true;
                break;
            }
            siblingElement = siblingElement.nextElementSibling;
        }
        if (obscured) return false;
    }

    // If all checks have passed, the element is visible
    return 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');
}

这是一种确定所有css属性(包括可见性)的方法:

html:

<div id="element">div content</div>

css:

#element
{
visibility:hidden;
}

javascript:

var element = document.getElementById('element');
 if(element.style.visibility == 'hidden'){
alert('hidden');
}
else
{
alert('visible');
}

它适用于任何css属性,非常通用和可靠。

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

//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

这就是我所做的:

HTML和CSS:默认情况下使元素隐藏

<html>
<body>

<button onclick="myFunction()">Click Me</button>

<p id="demo" style ="visibility: hidden;">Hello World</p> 

</body>
</html> 

JavaScript:增加了一个代码来检查可见性是否被隐藏:

<script>
function myFunction() {
   if ( document.getElementById("demo").style.visibility === "hidden"){
   document.getElementById("demo").style.visibility = "visible";
   }
   else document.getElementById("demo").style.visibility = "hidden";
}
</script>

根据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可能更简单一点,因为它考虑了更多的边缘情况,但我打赌它也会慢很多,所以如果你不得不多次重复这个操作,最好避免它。