监听div滚动事件未触发,需同时满足:容器有固定height/max-height、overflow-y为auto/scroll、子内容高度超过容器高度;应使用container.scrollTop获取局部滚动位置,避免window.scrollY;移动端需双监听scroll和touchmove(passive: false);必须用requestAnimationFrame节流整个业务逻辑。

监听 div 滚动事件却没触发?先确认两个硬条件
90% 的“监听不到”问题,不是 JS 写错了,而是容器根本不可滚动。必须同时满足:
• 容器有明确的 height 或 max-height(不能是 height: auto)
• 容器设置了 overflow-y: auto 或 overflow-y: scroll
• 容器子内容总高度 > 容器自身高度,即 scrollHeight > clientHeight
调试时直接打开 DevTools → Elements 面板 → 选中该 div → 看右侧面板的 Computed 样式,确认 overflow 计算值是否为 auto/scroll,再比对 scrollHeight 和 clientHeight 数值。
获取局部滚动位置该用 scrollTop,别碰 window.scrollY
监听的是某个 div,它的滚动偏移量和页面无关。window.scrollY 始终返回整个窗口的垂直滚动距离,对局部容器完全无效。
正确做法:
• 绑定事件:用 container.addEventListener('scroll', handler),不是 window
• 读取位置:在回调里访问 this.scrollTop 或 container.scrollTop
• 水平方向:对应用 this.scrollLeft
立即学习“前端免费学习笔记(深入)”;
注意:不要在回调外缓存 scrollTop 值——它只在滚动发生时实时更新,静态读取可能过期或为 0。
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
移动端 touch 滚动可能不触发 scroll?补监听 touchmove 并设 passive: false
某些安卓 WebView(如旧版 UC、部分定制浏览器)在快速拖拽时,scroll 事件会延迟甚至丢失首帧。此时仅靠 scroll 监听,scrollTop 可能长时间卡在初始值。
稳妥方案是双监听:
• 保留 scroll 作为主通道
• 同时给容器加 touchmove 监听,并显式传入 { passive: false }
• 在 touchmove 回调里也读 this.scrollTop(不是 event.touches[0].pageY)
关键点:passive: false 是必须的,否则 preventDefault() 会被静默忽略,且 Chrome 控制台会报错 Unable to preventDefault inside passive event listener。
节流不是可选,是防止卡顿的底线
局部容器滚动同样高频——尤其在手指滑动或鼠标滚轮加速时,scroll 每秒可触发数十次。若回调里做 DOM 查询、样式计算或 getBoundingClientRect(),立刻掉帧。
推荐用 requestAnimationFrame 节流,比手写 setTimeout 更稳:
• 声明一个 ticking 标志位
• 在 scroll 回调里只判断是否需要调度下一帧
• 把所有实际逻辑(包括读 scrollTop)放进 requestAnimationFrame 回调里
最易被忽略的一点:节流必须包裹“整个业务逻辑”,不只是 console.log。比如你要根据 scrollTop 切换 class 或触发动画,这些操作都得在 rAF 里执行,不能只节流读值那一步。


















