是否有一种有效的方法来判断DOM元素(在HTML文档中)当前是否可见(出现在视口中)?
(这个问题指的是Firefox。)
是否有一种有效的方法来判断DOM元素(在HTML文档中)当前是否可见(出现在视口中)?
(这个问题指的是Firefox。)
当前回答
我认为这是一种更实用的方法。 Dan的答案在递归上下文中不起作用。
此函数通过递归测试HTML标记之前的任何级别,并在第一个false处停止,解决了当您的元素位于其他可滚动div中的问题。
/**
* fullVisible=true only returns true if the all object rect is visible
*/
function isReallyVisible(el, fullVisible) {
if ( el.tagName == "HTML" )
return true;
var parentRect=el.parentNode.getBoundingClientRect();
var rect = arguments[2] || el.getBoundingClientRect();
return (
( fullVisible ? rect.top >= parentRect.top : rect.bottom > parentRect.top ) &&
( fullVisible ? rect.left >= parentRect.left : rect.right > parentRect.left ) &&
( fullVisible ? rect.bottom <= parentRect.bottom : rect.top < parentRect.bottom ) &&
( fullVisible ? rect.right <= parentRect.right : rect.left < parentRect.right ) &&
isReallyVisible(el.parentNode, fullVisible, rect)
);
};
其他回答
我尝试了Dan的答案,然而,用于确定边界的代数意味着元素必须既≤视口大小,又完全在视口内才能为真,很容易导致假否定。如果你想确定一个元素是否在视口中,ryanve的答案是接近的,但被测试的元素应该与视口重叠,所以试试这个:
function isElementInViewport(el) {
var rect = el.getBoundingClientRect();
return rect.bottom > 0 &&
rect.right > 0 &&
rect.left < (window.innerWidth || document.documentElement.clientWidth) /* or $(window).width() */ &&
rect.top < (window.innerHeight || document.documentElement.clientHeight) /* or $(window).height() */;
}
查看verge的源代码,它使用getBoundingClientRect。这就像:
function inViewport (element) {
if (!element) return false;
if (1 !== element.nodeType) return false;
var html = document.documentElement;
var rect = element.getBoundingClientRect();
return !!rect &&
rect.bottom >= 0 &&
rect.right >= 0 &&
rect.left <= html.clientWidth &&
rect.top <= html.clientHeight;
}
如果元素的任何部分在视口中,则返回true。
这里所有的答案都是确定元素是否完全包含在视口中,而不仅仅是以某种方式可见。例如,如果在视图的底部只有图像的一半可见,这里的解决方案将失败,考虑到“外部”。
我有一个用例,我正在通过IntersectionObserver进行惰性加载,但由于弹出过程中发生的动画,我不想观察任何已经在页面加载上交叉的图像。为此,我使用了以下代码:
const bounding = el.getBoundingClientRect();
const isVisible = (0 < bounding.top && bounding.top < (window.innerHeight || document.documentElement.clientHeight)) ||
(0 < bounding.bottom && bounding.bottom < (window.innerHeight || document.documentElement.clientHeight));
这基本上是检查顶部或底部边界是否在视口中独立。另一端可能在外面,但只要一端在里面,它至少是部分“可见”的。
这是一个简单而简单的解决方法,对我来说很有效。
示例:您想查看元素在具有溢出滚动的父元素中是否可见。
$(window).on('scroll', function () {
var container = $('#sidebar');
var containerHeight = container.height();
var scrollPosition = $('#row1').offset().top - container.offset().top;
if (containerHeight < scrollPosition) {
console.log('not visible');
} else {
console.log('visible');
}
})
我使用这个函数(它只检查y是否在屏幕上,因为大多数时候x是不需要的)
function elementInViewport(el) {
var elinfo = {
"top":el.offsetTop,
"height":el.offsetHeight,
};
if (elinfo.top + elinfo.height < window.pageYOffset || elinfo.top > window.pageYOffset + window.innerHeight) {
return false;
} else {
return true;
}
}