推荐使用addeventlistener('wheel', handler, { passive: false }),因其符合标准、支持事件移除与选项控制;内联onwheel破坏分离原则,jquery .on('wheel')仅限已用jquery项目;需注意passive: false才能调用preventdefault(),且deltay方向与wheeldelta相反。

onwheel 事件绑定的三种写法,选哪个?
直接在 HTML 标签里写 onwheel 最快,但不推荐;用 addEventListener 是标准做法,兼容性好、可移除、支持选项控制;jQuery 的 .on('wheel') 只在项目已用 jQuery 时才考虑,额外开销没必要。
-
onwheel是原生 DOM 事件,不是 jQuery 自定义事件,别和scroll混用 - HTML 内联写法:
<div onwheel="handleWheel(event)"></div>—— 调试方便但破坏结构/样式/行为分离 - 推荐 JS 绑定:
element.addEventListener('wheel', handleWheel, { passive: false })—— 注意passive默认为true,设false才能调用event.preventDefault()
为什么 preventDefault() 有时没用?
Chrome 和 Firefox 默认把 wheel 事件标记为 passive,意味着浏览器假设你不会调用 preventDefault(),提前滚动了。这时候再阻止就无效,控制台还会报警告:「Unable to preventDefault inside passive event listener」。
- 必须显式传
{ passive: false }到addEventListener第三个参数 - 如果只是读取
event.deltaY做缩放或切换,不需要阻止默认行为,可以设passive: true(性能更好) - 移动端 Safari 对
passive: false支持较晚,iOS 13.4+ 才稳定,旧版本可能静默降级
deltaX/deltaY/deltaMode 怎么看方向和单位?
event.deltaY 是最常用属性,负值表示向上滚(内容往上移),正值表示向下滚(内容往下移);单位取决于 event.deltaMode:0 是像素,1 是行,2 是页 —— 大多数鼠标是 0,但触控板或某些笔记本可能返回 1。
- 别只依赖
deltaY > 0判断“向下”,要结合deltaMode归一化处理,比如:const delta = event.deltaMode === 1 ? event.deltaY * 40 : event.deltaY -
deltaX在水平滚动或 shift+滚轮时触发,但很多鼠标默认不触发,需测试实际设备 - 避免用
event.wheelDelta(IE/旧 WebKit),它已被废弃,值和符号逻辑与deltaY相反
滚动节流为什么不能只靠 throttle?
wheel 事件频率极高(尤其触控板),直接在里面做重操作会卡顿。但光套个 throttle 不够 —— 因为滚轮连续触发时,节流会丢掉中间帧,导致“跳变”感;更稳的方式是用 requestAnimationFrame + 累积 delta。
- 典型错误:
throttle(handleWheel, 16)—— 仍可能因帧率抖动造成响应滞后 - 推荐模式:在
wheel里只累加pendingDelta += event.deltaY,然后requestAnimationFrame里统一处理并清空 - 注意:如果用了
passive: false,就不能在requestAnimationFrame里调preventDefault(),必须在原事件回调里调
滚动事件的细节全藏在 passive、deltaMode 和帧调度配合里,漏掉任意一个,要么失效,要么卡顿,要么兼容出问题。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











