用 scroll 事件判断滚动方向需缓存上一次 scrolltop 值(lastscrolltop),在回调中读取当前值比较差值:current > last 向下,反之向上;wheel 事件则通过 e.deltay 符号判断,建议加阈值过滤微小变化。

怎么用 scroll 事件判断滚动方向?
靠 scrollTop 差值判断最直接,但必须缓存上一次的值,不能只看当前——因为单次事件里没有“变化量”。window.onscroll 或 addEventListener('scroll', ...) 都行,关键是维护一个 lastScrollTop 变量。
常见错误是写成 if (window.scrollTop > 0) { 向下 },这只能判断“是否滚过顶部”,不是方向。
- 初始化时设
let lastScrollTop = window.pageYOffset || document.documentElement.scrollTop - 在 scroll 回调里重新读当前值:
const currentScrollTop = window.pageYOffset || document.documentElement.scrollTop - 比较:
if (currentScrollTop > lastScrollTop) { /* 向下 */ } else if (currentScrollTop - 别忘了更新
lastScrollTop = currentScrollTop,否则后续判断全失效
wheel 事件里怎么拿到精确方向?
wheel 比 scroll 更底层、更及时,适合做即时反馈(比如滚动加速、方向高亮),但它不反映最终滚动位置,只告诉你“用户刚往哪滚了一轮”。
核心是 event.deltaY:正值 = 向下滚动,负值 = 向上滚动。注意它和鼠标滚轮物理方向一致,跟页面内容是否真动了无关。
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
- 监听:
element.addEventListener('wheel', e => { if (e.deltaY > 0) { /* 向下触发 */ } }) - 要区分横竖滚动?同时看
e.deltaX和e.deltaY:若Math.abs(e.deltaY) > Math.abs(e.deltaX),优先按纵向处理 - 某些触控板会触发
deltaY极小值(如 ±0.1),建议加阈值过滤:if (Math.abs(e.deltaY) - 不要在
wheel里直接调preventDefault(),除非你明确接管了滚动逻辑;否则可能禁掉原生滚动
自定义滚动容器里方向检测为啥总错?
当滚动目标不是 window,而是某个 div(比如聊天窗口、列表弹层),pageYOffset 就完全没用了——它永远只反映视口滚动。
必须换用该容器自身的 scrollTop,且要确保它真的在滚动:CSS 得有 overflow-y: auto + 明确高度,否则 scrollTop 始终为 0。
- 正确获取:
const container = document.getElementById('chat-list'); const st = container.scrollTop - 错误写法:
window.pageYOffset或document.body.scrollTop—— 这俩对局部容器无效 - 监听方式必须是
container.addEventListener('scroll', ...),不是window上的 - 首次监听前,先手动读一次
container.scrollTop作为初始值,避免第一次比较失真
为什么 iOS 上滚动方向检测容易抖动或延迟?
iOS WebKit 对 scroll 事件做了节流,默认每帧最多触发一次,且常延迟一帧;wheel 在 iOS Safari 里基本不触发(触控板除外);再加上弹性滚动(overscroll)导致 scrollTop 在回弹过程中来回跳变。
实际能依赖的只有 scroll 事件 + 合理防抖,别指望高频精准。
- 放弃“实时方向”幻想,改用「滚动开始后 100ms 内首次方向」作为判定依据
- 用
requestAnimationFrame包一层读取,比直接在事件里读更稳:requestAnimationFrame(() => { /* 读 scrollTop */ }) - 避免在
scroll里做 heavy work(比如重排 DOM、发起请求),否则加剧丢帧和方向误判 - 如果只是要做“吸顶/隐藏 header”,优先用 CSS
position: sticky,比 JS 检测可靠得多
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










