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

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

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

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

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

还有我可能漏掉的吗?


当前回答

公认的答案对我不起作用。

2020年分解。

The (elem.offsetParent !== null) method works fine in Firefox but not in Chrome. In Chrome position: fixed will also make offsetParent return null even the element if visible in the page. User Phrogz conducted a large test (2,304 divs) on elements with varying properties to demonstrate the issue. https://stackoverflow.com/a/11639664/4481831 . Run it with multiple browsers to see the differences. Demo: //different results in Chrome and Firefox console.log(document.querySelector('#hidden1').offsetParent); //null Chrome & Firefox console.log(document.querySelector('#fixed1').offsetParent); //null in Chrome, not null in Firefox <div id="hidden1" style="display:none;"></div> <div id="fixed1" style="position:fixed;"></div> The (getComputedStyle(elem).display !== 'none') does not work because the element can be invisible because one of the parents display property is set to none, getComputedStyle will not catch that. Demo: var child1 = document.querySelector('#child1'); console.log(getComputedStyle(child1).display); //child will show "block" instead of "none" <div id="parent1" style="display:none;"> <div id="child1" style="display:block"></div> </div> The (elem.clientHeight !== 0). This method is not influenced by position: fixed and it also check if element parents are not-visible. But it has problems with simple elements that do not have a css layout and inline elements, see more here Demo: console.log(document.querySelector('#inline1').clientHeight); //zero console.log(document.querySelector('#div1').clientHeight); //not zero console.log(document.querySelector('#span1').clientHeight); //zero <div id="inline1" style="display:inline">test1 inline</div> <div id="div1">test2 div</div> <span id="span1">test3 span</span> The (elem.getClientRects().length !== 0) may seem to solve the problems of the previous 3 methods. However it has problems with elements that use CSS tricks (other then display: none) to hide in the page. Demo console.log(document.querySelector('#notvisible1').getClientRects().length); console.log(document.querySelector('#notvisible1').clientHeight); console.log(document.querySelector('#notvisible2').getClientRects().length); console.log(document.querySelector('#notvisible2').clientHeight); console.log(document.querySelector('#notvisible3').getClientRects().length); console.log(document.querySelector('#notvisible3').clientHeight); <div id="notvisible1" style="height:0; overflow:hidden; background-color:red;">not visible 1</div> <div id="notvisible2" style="visibility:hidden; background-color:yellow;">not visible 2</div> <div id="notvisible3" style="opacity:0; background-color:blue;">not visible 3</div>

结论。

所以我向你们展示的是没有什么方法是完美的。要进行适当的可见性检查,必须结合使用后3种方法。

其他回答

这可能会有帮助: 将元素隐藏在最左边的位置,然后检查offsetLeft属性。如果你想使用jQuery,你可以简单地检查:visible选择器并获得元素的可见状态。

HTML:

<div id="myDiv">Hello</div>

CSS:

<!-- for javaScript-->
#myDiv{
   position:absolute;
   left : -2000px;
}

<!-- for jQuery -->
#myDiv{
    visibility:hidden;
}

javaScript:

var myStyle = document.getElementById("myDiv").offsetLeft;

if(myStyle < 0){
     alert("Div is hidden!!");
}

jQuery:

if(  $("#MyElement").is(":visible") == true )
{  
     alert("Div is visible!!");        
}

js小提琴

这是一种确定所有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属性,非常通用和可靠。

2021的解决方案

根据MDN文档,交互观察器异步观察目标元素与祖先元素或顶级文档视口的交集中的变化。这意味着每当元素与视口相交时,交互观察器就会触发。

截至2021年,除IE外,目前所有浏览器都支持交集观测器。

实现

const el = document.getElementById("your-target-element");
const observer = new IntersectionObserver((entries) => {
    if(entries[0].isIntersecting){
         // el is visible
    } else {
         // el is not visible
    }
});

observer.observe(el); // Asynchronous call

The handler will fire when initially created. And then it will fire every time that it becomes slightly visible or becomes completely not visible. An element is deemed to be not-visible when it's not actually visible within the viewport. So if you scroll down and element goes off the screen, then the observer will trigger and the // el is not visible code will be triggered - even though the element is still "displayed" (i.e. doesn't have display:none or visibility:hidden). What matters is whether there are any pixels of the element that are actually visible within the viewport.

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

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

这是基于以下事实:

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

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

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

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

活塞(点击这里)