是否有一种有效的方法来判断DOM元素(在HTML文档中)当前是否可见(出现在视口中)?
(这个问题指的是Firefox。)
是否有一种有效的方法来判断DOM元素(在HTML文档中)当前是否可见(出现在视口中)?
(这个问题指的是Firefox。)
当前回答
让我感到困扰的是,该功能没有以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
}
});
其他回答
const isHTMLElementInView = (element: HTMLElement) => {
const rect = element?.getBoundingClientRect()
if (!rect) return
return rect.top <= window.innerHeight && rect.bottom >= 0
}
这个函数检查元素是否在垂直水平的视口中。
下面是检查给定元素在其父元素中是否完全可见的代码片段:
export const visibleInParentViewport = (el) => {
const elementRect = el.getBoundingClientRect();
const parentRect = el.parentNode.getBoundingClientRect();
return (
elementRect.top >= parentRect.top &&
elementRect.right >= parentRect.left &&
elementRect.top + elementRect.height <= parentRect.bottom &&
elementRect.left + elementRect.width <= parentRect.right
);
}
更新:时间在流逝,我们的浏览器也是如此。这种方法不再被推荐,如果你不需要支持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
);
}
我在这里遇到的所有答案都只是检查元素是否位于当前视口中。但这并不意味着它是可见的。 如果给定的元素在一个包含满溢内容的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>