Rus*_*rry 10 javascript javascript-events
当某个DIV进入页面时,是否可以触发特定的javascript事件?
比方说,我有一个非常大的页面,比如2500x2500,我有一个位于1980x1250位置的40x40 div.div不一定是手动定位的,它可能存在,因为内容将其推到那里.现在,当用户滚动到div可见的点时,是否可以运行一个函数?
bob*_*nce 10
不是自动的.您必须通过比较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>
Run Code Online (Sandbox Code Playgroud)
您可以通过以下方式改进:
onscroll
所有拥有overflow
scroll
或auto
调整顶部/左侧坐标的祖先的滚动位置overflow
scroll
,auto
并hidden
裁剪把DIV离屏addEventListener
/ attachEvent
允许使用调整大小/滚动事件的多个VisibilityMonitors和其他内容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"));
Run Code Online (Sandbox Code Playgroud)
一旦该项目部分显示在屏幕上,就会触发此操作。将阈值更改为 1 将要求该项目完全显示在屏幕上(因此,如果该项目大于视口,它将永远不会触发)。您可以设置介于 0.25 之间的值,以便在至少 1/4 的项目处于视图中时触发。