是否有一种有效的方法来判断DOM元素(在HTML文档中)当前是否可见(出现在视口中)?
(这个问题指的是Firefox。)
是否有一种有效的方法来判断DOM元素(在HTML文档中)当前是否可见(出现在视口中)?
(这个问题指的是Firefox。)
当前回答
在我看来,非常简单:
function isVisible(elem) {
var coords = elem.getBoundingClientRect();
return Math.abs(coords.top) <= coords.height;
}
其他回答
让我感到困扰的是,该功能没有以jquery为中心的版本可用。当我看到Dan的解决方案时,我发现有机会为那些喜欢用jQuery OO风格编程的人提供一些东西。它很漂亮,很时髦,对我来说很有魅力。
哒哒,哒哒,嘣
$.fn.inView = function(){
if(!this.length)
return false;
var rect = this.get(0).getBoundingClientRect();
return (
rect.top >= 0 &&
rect.left >= 0 &&
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
rect.right <= (window.innerWidth || document.documentElement.clientWidth)
);
};
// Additional examples for other use cases
// Is true false whether an array of elements are all in view
$.fn.allInView = function(){
var all = [];
this.forEach(function(){
all.push( $(this).inView() );
});
return all.indexOf(false) === -1;
};
// Only the class elements in view
$('.some-class').filter(function(){
return $(this).inView();
});
// Only the class elements not in view
$('.some-class').filter(function(){
return !$(this).inView();
});
使用
$(window).on('scroll',function(){
if( $('footer').inView() ) {
// Do cool stuff
}
});
我使用这个函数(它只检查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;
}
}
我在这里遇到的所有答案都只是检查元素是否位于当前视口中。但这并不意味着它是可见的。 如果给定的元素在一个包含满溢内容的div中,并且它被滚动到视图之外,该怎么办?
要解决这个问题,您必须检查元素是否被所有父元素所包含。 我的解决方案就是这样:
它还允许您指定多少元素必须是可见的。
Element.prototype.isVisible = function(percentX, percentY){
var tolerance = 0.01; //needed because the rects returned by getBoundingClientRect provide the position up to 10 decimals
if(percentX == null){
percentX = 100;
}
if(percentY == null){
percentY = 100;
}
var elementRect = this.getBoundingClientRect();
var parentRects = [];
var element = this;
while(element.parentElement != null){
parentRects.push(element.parentElement.getBoundingClientRect());
element = element.parentElement;
}
var visibleInAllParents = parentRects.every(function(parentRect){
var visiblePixelX = Math.min(elementRect.right, parentRect.right) - Math.max(elementRect.left, parentRect.left);
var visiblePixelY = Math.min(elementRect.bottom, parentRect.bottom) - Math.max(elementRect.top, parentRect.top);
var visiblePercentageX = visiblePixelX / elementRect.width * 100;
var visiblePercentageY = visiblePixelY / elementRect.height * 100;
return visiblePercentageX + tolerance > percentX && visiblePercentageY + tolerance > percentY;
});
return visibleInAllParents;
};
这个解决方案忽略了元素可能由于其他因素而不可见的事实,比如不透明度:0。
我已经在Chrome和Internet Explorer 11中测试了这个解决方案。
我们现在有一个原生javascript交集观察者API 从中我们可以检测元素,无论它们是否在视口中。
这里有一个例子
const el = document.querySelector('#el') const observer = new window.IntersectionObserver(([entry]) => { if (entry. isintersection) { console.log(输入) 返回 } console.log(离开) }, { 根:空, 阈值:0.1,//设置偏移量0.1表示如果元素在视口中至少占10%,则触发 }) observer.observe (el); 身体{ 身高:300 vh; } # el { margin-top: 100 vh; } <div id="el">这是元素</div>
在Android上放大谷歌Chrome浏览器时,最被接受的答案是不工作的。结合Dan的回答,要考虑Android上的Chrome,必须使用visualViewport。下面的例子只考虑了垂直检查,并使用jQuery来计算窗口高度:
var Rect = YOUR_ELEMENT.getBoundingClientRect();
var ElTop = Rect.top, ElBottom = Rect.bottom;
var WindowHeight = $(window).height();
if(window.visualViewport) {
ElTop -= window.visualViewport.offsetTop;
ElBottom -= window.visualViewport.offsetTop;
WindowHeight = window.visualViewport.height;
}
var WithinScreen = (ElTop >= 0 && ElBottom <= WindowHeight);