当某个 DIV 出现在页面上时,是否可能触发特定的 JavaScript 事件?
比如说,我有一个非常大的页面,像是 2500x2500,而我有一个大小为 40x40 的 DIV,它位于 1980x1250 的位置。这个 div 不一定是手动定位的,它可能是由于内容推动它到那里的。那么,当用户滚动到 div 可见的位置时,是否可能运行一个函数?
当某个 DIV 出现在页面上时,是否可能触发特定的 JavaScript 事件?
比如说,我有一个非常大的页面,像是 2500x2500,而我有一个大小为 40x40 的 DIV,它位于 1980x1250 的位置。这个 div 不一定是手动定位的,它可能是由于内容推动它到那里的。那么,当用户滚动到 div 可见的位置时,是否可能运行一个函数?
不是自动的。您需要捕捉滚动事件并每次通过比较div矩形的坐标与可见页面矩形来检查它是否在视图中。
这是一个最简示例。
<div id="importantdiv">hello</div>
<script type="text/javascript">
function VisibilityMonitor(element, showfn, hidefn) {
var isshown= false;
function check() {
if (rectsIntersect(getPageRect(), getElementRect(element)) !== isshown) {
isshown= !isshown;
isshown? showfn() : hidefn();
}
};
window.onscroll=window.onresize= check;
check();
}
function getPageRect() {
var isquirks= document.compatMode!=='BackCompat';
var page= isquirks? document.documentElement : document.body;
var x= page.scrollLeft;
var y= page.scrollTop;
var w= 'innerWidth' in window? window.innerWidth : page.clientWidth;
var h= 'innerHeight' in window? window.innerHeight : page.clientHeight;
return [x, y, x+w, y+h];
}
function getElementRect(element) {
var x= 0, y= 0;
var w= element.offsetWidth, h= element.offsetHeight;
while (element.offsetParent!==null) {
x+= element.offsetLeft;
y+= element.offsetTop;
element= element.offsetParent;
}
return [x, y, x+w, y+h];
}
function rectsIntersect(a, b) {
return a[0]<b[2] && a[2]>b[0] && a[1]<b[3] && a[3]>b[1];
}
VisibilityMonitor(
document.getElementById('importantdiv'),
function() {
alert('div in view!');
},
function() {
alert('div gone away!');
}
);
</script>
您可以通过以下方法改进:
overflow
scroll
或auto
的所有祖先元素捕获onscroll
事件,并调整它们的滚动位置的顶部/左侧坐标。overflow
scroll
、auto
和hidden
属性,将div放在屏幕外进行裁剪。addEventListener
/attachEvent
允许多个可见性监视器以及使用resize/scroll事件的其他功能。getElementRect
进行修改,在某些情况下使坐标更准确,并且一些解除绑定事件以避免IE6-7内存泄漏(如果确实需要)。这里是一个在2022年非常理想的解决方案。当前最佳答案只能允许您观察一个项目,而且因为每次滚动页面时都会触发很多次,所以存在性能问题。
var observer = new IntersectionObserver(function(entries) {
if(entries[0].isIntersecting === true) {
console.log('Item has just APPEARED!');
} else {
console.log('Item has just DISAPPEARED!');
}
}, { threshold: [0] });
observer.observe(document.querySelector("#DIV-TO-OBSERVE"));
此事件在项目部分显示在屏幕上时立即触发。将阈值更改为1将要求项目完全显示在屏幕上(因此如果项目大于视口,则永远不会触发)。您可以在中间使用值,例如0.25,以便当至少显示项目的四分之一时触发该事件。
以下是一个使用 jQuery 的入门示例:
<html>
<head><title>In View</title></head>
<body>
<div style="text-align:center; font-size:larger" id="top"></div>
<fieldset style="text-align:center; font-size:larger" id="middle">
<legend id="msg"></legend>
<div> </div>
<div id="findme">Here I am!!!</div>
</fieldset>
<div style="text-align:center; font-size:larger" id="bottom"></div>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">
var $findme = $('#findme'),
$msg = $('#msg');
function Scrolled() {
var findmeOffset = $findme.offset(),
findmeTop = findmeOffset.top,
scrollTop = $(document).scrollTop(),
visibleBottom = window.innerHeight;
if (findmeTop < scrollTop + visibleBottom) {
$msg.text('findme is visible');
}
else {
$msg.text('findme is NOT visible');
}
}
function Setup() {
var $top = $('#top'),
$bottom = $('#bottom');
$top.height(500);
$bottom.height(500);
$(window).scroll(function() {
Scrolled();
});
}
$(document).ready(function() {
Setup();
});
</script>
</body>
</html>
只有在 div 从底部进入视图时才会发出通知。此示例在 div 滚动到顶部时不会发出通知。