有什么方法,我可以检查如果一个元素是可见的纯JS(没有jQuery) ?
因此,给定一个DOM元素,我如何检查它是否可见?我试着:
window.getComputedStyle(my_element)['display']);
但这似乎并不奏效。我想知道我应该检查哪些属性。我想到了:
display !== 'none'
visibility !== 'hidden'
还有我可能漏掉的吗?
有什么方法,我可以检查如果一个元素是可见的纯JS(没有jQuery) ?
因此,给定一个DOM元素,我如何检查它是否可见?我试着:
window.getComputedStyle(my_element)['display']);
但这似乎并不奏效。我想知道我应该检查哪些属性。我想到了:
display !== 'none'
visibility !== 'hidden'
还有我可能漏掉的吗?
当前回答
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.
其他回答
来自http://code.jquery.com/jquery-1.11.1.js的jQuery代码有一个isHidden参数
var isHidden = function( elem, el ) {
// isHidden might be called from jQuery#filter function;
// in that case, element will be second argument
elem = el || elem;
return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem );
};
因此,看起来有一个与所有者文档相关的额外检查
我想知道这是否真的适用于以下情况:
基于zIndex隐藏在其他元素后面的元素 完全透明的元素使它们不可见 位于屏幕外的元素(即左:-1000px) 具有可见性的元素:隐藏 有显示的元素:无 没有可见文本或子元素的元素 高度或宽度设置为0的元素
如果我们只是收集检测能见度的基本方法,让我不要忘记:
opacity > 0.01; // probably more like .1 to actually be visible, but YMMV
至于如何获取属性:
element.getAttribute(attributename);
所以,在你的例子中:
document.getElementById('snDealsPanel').getAttribute('visibility');
But wha? It doesn't work here. Look closer and you'll find that visibility is being updated not as an attribute on the element, but using the style property. This is one of many problems with trying to do what you're doing. Among others: you can't guarantee that there's actually something to see in an element, just because its visibility, display, and opacity all have the correct values. It still might lack content, or it might lack a height and width. Another object might obscure it. For more detail, a quick Google search reveals this, and even includes a library to try solving the problem. (YMMV)
看看下面的问题,它们可能是这个问题的副本,有很好的答案,包括来自强大的约翰·雷西格的一些见解。但是,您的特定用例与标准用例略有不同,因此我将避免标记:
如何判断一个DOM元素是否在当前视口中可见? 如何检查一个元素是否真的可见javascript?
(EDIT: OP SAYS HE'S SCRAPING PAGES, NOT CREATING THEM, SO BELOW ISN'T APPLICABLE) A better option? Bind the visibility of elements to model properties and always make visibility contingent on that model, much as Angular does with ng-show. You can do that using any tool you want: Angular, plain JS, whatever. Better still, you can change the DOM implementation over time, but you'll always be able to read state from the model, instead of the DOM. Reading your truth from the DOM is Bad. And slow. Much better to check the model, and trust in your implementation to ensure that the DOM state reflects the model. (And use automated testing to confirm that assumption.)
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.
改进了上面@Guy Messika的回答,如果中心点' X < 0是错误的,则中断并返回false,因为元素右侧可能会进入视图。这里有一个解决方案:
private isVisible(elem) {
const style = getComputedStyle(elem);
if (style.display === 'none') return false;
if (style.visibility !== 'visible') return false;
if ((style.opacity as any) === 0) return false;
if (
elem.offsetWidth +
elem.offsetHeight +
elem.getBoundingClientRect().height +
elem.getBoundingClientRect().width === 0
) return false;
const elementPoints = {
center: {
x: elem.getBoundingClientRect().left + elem.offsetWidth / 2,
y: elem.getBoundingClientRect().top + elem.offsetHeight / 2,
},
topLeft: {
x: elem.getBoundingClientRect().left,
y: elem.getBoundingClientRect().top,
},
topRight: {
x: elem.getBoundingClientRect().right,
y: elem.getBoundingClientRect().top,
},
bottomLeft: {
x: elem.getBoundingClientRect().left,
y: elem.getBoundingClientRect().bottom,
},
bottomRight: {
x: elem.getBoundingClientRect().right,
y: elem.getBoundingClientRect().bottom,
},
};
const docWidth = document.documentElement.clientWidth || window.innerWidth;
const docHeight = document.documentElement.clientHeight || window.innerHeight;
if (elementPoints.topLeft.x > docWidth) return false;
if (elementPoints.topLeft.y > docHeight) return false;
if (elementPoints.bottomRight.x < 0) return false;
if (elementPoints.bottomRight.y < 0) return false;
for (let index in elementPoints) {
const point = elementPoints[index];
let pointContainer = document.elementFromPoint(point.x, point.y);
if (pointContainer !== null) {
do {
if (pointContainer === elem) return true;
} while (pointContainer = pointContainer.parentNode);
}
}
return false;
}
有许多情况下,这将不一定工作,但在我的情况下,我正在使用这个,它为我所需要的工作。所以,如果你正在寻找一个基本的解决方案(不包括所有的可能性),如果这个简单的解决方案适合你的特殊需求,它“可能”对你有帮助。
var element= document.getElementById('elementId');
if (element.style.display == "block"){
<!-- element is visible -->
} else {
<!-- element is hidden-->
}