如何使用IntersectionObserver判断页面是否处于顶部
问题:IntersectionObserver判断页面顶部逻辑错误,红色盒子不可见时仍输出顶部状态
需求与问题描述
我尝试用IntersectionObserver判断页面是否处于顶部,判定条件为:
- 向下滚动距离未超过60px(
document.documentElement.scrollTop < 60) - 红色盒子的任意部分可见(红色盒子标记自定义的页面顶部区域)
预期效果:
- 页面处于顶部时,控制台输出
console.log('we are at the top') - 页面未处于顶部时,控制台输出
console.log('we are not at the top')
当前问题:红色盒子不可见时,控制台仍输出‘we are at the top’
相关代码
HTML
<div id="root"> <div class="red-box"></div> <section class="bg-blue py-60"></section> <section class="bg-green py-60"></section> <section class="bg-purple py-60"></section> </div>
CSS
* { margin: 0; padding: 0; } #root { position: relative; height: 100vh; width: 100%; overflow: auto; } .red-box { height: 60px; width: 100%; position: absolute; border: 5px solid red; } .bg-blue { background: blue; } .bg-green { background: green; } .bg-purple { background: purple; } .py-60 { padding: 40rem 0; }
原JS代码
const root = document.querySelector("#root"); const firstSection = document.querySelectorAll("section")[0]; const onIntersect = (entries) => { entries.forEach((entry) => { if (entry.isIntersecting && document.documentElement.scrollTop <= 60) { console.log("WE ARE AT THE TOP"); } else { console.log("WE ARE NOT AT THE TOP"); } }); }; const observer = new IntersectionObserver(onIntersect, { root: root, }); observer.observe(firstSection);
问题根源与修复方案
问题核心
你当前监听的是第一个蓝色section,而非用来判定顶部的红色盒子。当红色盒子被滚动移出视口时,第一个section可能仍处于相交状态,再加上scrollTop <=60的条件可能还未失效,就会错误输出顶部状态。
修复步骤
- 将监听目标从第一个section改为红色盒子
- 保持原有的双条件判定逻辑,确保只有红色盒子可见且滚动距离不超过60px时,才判定为顶部
修改后的JS代码
const root = document.querySelector("#root"); // 切换监听目标为红色盒子 const redBox = document.querySelector(".red-box"); const onIntersect = (entries) => { entries.forEach((entry) => { if (entry.isIntersecting && document.documentElement.scrollTop <= 60) { console.log("WE ARE AT THE TOP"); } else { console.log("WE ARE NOT AT THE TOP"); } }); }; const observer = new IntersectionObserver(onIntersect, { root: root, }); // 观察红色盒子 observer.observe(redBox);
补充说明
- 红色盒子是绝对定位,当滚动距离超过60px后,它会完全移出根容器视口,此时
entry.isIntersecting会变为false,结合滚动距离条件,就能正确判定非顶部状态。 - IntersectionObserver默认阈值为0,只要红色盒子有任意部分出现在根容器内,就会触发相交状态,符合你对“任意部分可见”的判定要求。
内容的提问来源于stack exchange,提问作者user19666029
相关产品推荐
相关产品推荐

