是否有一种有效的方法来判断DOM元素(在HTML文档中)当前是否可见(出现在视口中)?
(这个问题指的是Firefox。)
是否有一种有效的方法来判断DOM元素(在HTML文档中)当前是否可见(出现在视口中)?
(这个问题指的是Firefox。)
当前回答
这是我的解决方案。如果一个元素隐藏在一个可滚动的容器中,它将工作。
这里是一个演示(尝试调整窗口大小为)
var visibleY = function(el){
var top = el.getBoundingClientRect().top, rect, el = el.parentNode;
do {
rect = el.getBoundingClientRect();
if (top <= rect.bottom === false)
return false;
el = el.parentNode;
} while (el != document.body);
// Check it's within the document viewport
return top <= document.documentElement.clientHeight;
};
我只需要检查它在Y轴上是否可见(用于滚动Ajax加载更多记录功能)。
其他回答
我发现这里公认的答案对于大多数用例来说过于复杂。这段代码很好地完成了工作(使用jQuery),并区分了完全可见和部分可见的元素:
var element = $("#element");
var topOfElement = element.offset().top;
var bottomOfElement = element.offset().top + element.outerHeight(true);
var $window = $(window);
$window.bind('scroll', function() {
var scrollTopPosition = $window.scrollTop()+$window.height();
var windowScrollTop = $window.scrollTop()
if (windowScrollTop > topOfElement && windowScrollTop < bottomOfElement) {
// Element is partially visible (above viewable area)
console.log("Element is partially visible (above viewable area)");
} else if (windowScrollTop > bottomOfElement && windowScrollTop > topOfElement) {
// Element is hidden (above viewable area)
console.log("Element is hidden (above viewable area)");
} else if (scrollTopPosition < topOfElement && scrollTopPosition < bottomOfElement) {
// Element is hidden (below viewable area)
console.log("Element is hidden (below viewable area)");
} else if (scrollTopPosition < bottomOfElement && scrollTopPosition > topOfElement) {
// Element is partially visible (below viewable area)
console.log("Element is partially visible (below viewable area)");
} else {
// Element is completely visible
console.log("Element is completely visible");
}
});
我尝试了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() */;
}
更新:时间在流逝,我们的浏览器也是如此。这种方法不再被推荐,如果你不需要支持ie7之前的版本,你应该使用Dan的解决方案。
原来的解决方案(现已过时):
这将检查元素是否在当前视口中完全可见:
function elementInViewport(el) {
var top = el.offsetTop;
var left = el.offsetLeft;
var width = el.offsetWidth;
var height = el.offsetHeight;
while(el.offsetParent) {
el = el.offsetParent;
top += el.offsetTop;
left += el.offsetLeft;
}
return (
top >= window.pageYOffset &&
left >= window.pageXOffset &&
(top + height) <= (window.pageYOffset + window.innerHeight) &&
(left + width) <= (window.pageXOffset + window.innerWidth)
);
}
你可以简单地修改它,以确定元素的任何部分在视口中是否可见:
function elementInViewport2(el) {
var top = el.offsetTop;
var left = el.offsetLeft;
var width = el.offsetWidth;
var height = el.offsetHeight;
while(el.offsetParent) {
el = el.offsetParent;
top += el.offsetTop;
left += el.offsetLeft;
}
return (
top < (window.pageYOffset + window.innerHeight) &&
left < (window.pageXOffset + window.innerWidth) &&
(top + height) > window.pageYOffset &&
(left + width) > window.pageXOffset
);
}
作为Element.getBoundingClientRect()的支持,最简单的解决方案已经变得完美:
function isInView(el) {
const box = el.getBoundingClientRect();
return box.top < window.innerHeight && box.bottom >= 0;
}
我有同样的问题,并通过使用getBoundingClientRect()来解决。
这段代码完全是“通用的”,只需要写一次就可以工作(你不需要为你想知道的每个元素都写出来)。
这段代码只检查它在视口中是否垂直,而不是水平。在本例中,变量(array)'elements'保存了所有你要检查的垂直在视口中的元素,所以在任何地方抓取任何你想要的元素并将它们存储在那里。
for循环遍历每个元素并检查它是否垂直地位于视口中。这段代码在用户每次滚动时执行!如果getBoudingClientRect()。Top小于viewport的3/4(元素在viewport中的四分之一),它注册为“在viewport中”。
因为代码是通用的,你会想知道“哪个”元素在视口中。要找出这一点,可以通过自定义属性、节点名、id、类名等确定。
这是我的代码(如果它不起作用,请告诉我;它已在Internet Explorer 11、Firefox 40.0.3、Chrome Version 45.0.2454.85 m、Opera 31.0.1889.174和Edge with Windows 10(还没有Safari)上测试……
// Scrolling handlers...
window.onscroll = function(){
var elements = document.getElementById('whatever').getElementsByClassName('whatever');
for(var i = 0; i != elements.length; i++)
{
if(elements[i].getBoundingClientRect().top <= window.innerHeight*0.75 &&
elements[i].getBoundingClientRect().top > 0)
{
console.log(elements[i].nodeName + ' ' +
elements[i].className + ' ' +
elements[i].id +
' is in the viewport; proceed with whatever code you want to do here.');
}
};