鼠标滚轮事件在Web交互中非常实用,比如无限滚动加载、图片缩放、幻灯片切换等。本文围绕wheel事件及其deltaY属性,给出判断滚动方向的标准写法,并提供一个可运行的幻灯片切换示例,同时讨论旧浏览器的兼容方案。
## wheel事件与deltaY属性
现代浏览器推荐使用wheel事件替代已废弃的mousewheel。wheel事件对象包含deltaY属性,用于识别垂直滚动方向:
- deltaY < 0:向上滚动(用户手指或鼠标滚轮向前推)
- deltaY > 0:向下滚动(用户手指或鼠标滚轮向后拉)
此外,deltaX表示水平滚动,deltaZ基本用不到。
## 基本监听代码
直接使用addEventListener注册wheel事件即可。以下代码在控制台输出滚动方向:- document.addEventListener('wheel', (event) => {
- if (event.deltaY < 0) {
- console.log('向上滚动');
- // 执行向上滚动逻辑
- } else if (event.deltaY > 0) {
- console.log('向下滚动');
- // 执行向下滚动逻辑
- }
- });
复制代码 注意:如需阻止页面默认滚动(比如实现自定义滚动效果),可在事件处理函数开头调用event.preventDefault(),但必须谨慎使用,避免破坏基础滚动体验。
## 完整示例:阻止默认滚动 + 切换幻灯片
实际需求中常需要覆盖浏览器默认滚动,并触发自定义交互。下面以一个三层幻灯片切换为例,向上滚动翻到上一张,向下滚动翻到下一张:- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>滚轮切换幻灯片</title>
- <style>
- body {
- margin: 0;
- display: flex;
- justify-content: center;
- align-items: center;
- min-height: 100vh;
- background: #f5f5f5;
- font-family: Arial, sans-serif;
- }
- .slider {
- width: 500px;
- height: 300px;
- background: #f0f0f0;
- border-radius: 8px;
- position: relative;
- overflow: hidden;
- }
- .slide {
- position: absolute;
- width: 100%;
- height: 100%;
- display: flex;
- align-items: center;
- justify-content: center;
- font-size: 24px;
- transition: transform 0.5s ease;
- }
- </style>
- </head>
- <body>
- <div class="slider">
- <div class="slide" style="background: #ffcccc;">Slide 1</div>
- <div class="slide" style="background: #ccffcc;">Slide 2</div>
- <div class="slide" style="background: #ccccff;">Slide 3</div>
- </div>
- <script>
- const slides = document.querySelectorAll('.slide');
- let currentSlide = 0;
- // 初始只显示第一张
- function updateSlider() {
- slides.forEach((slide, index) => {
- slide.style.transform = `translateY(${(index - currentSlide) * 100}%)`;
- });
- }
- updateSlider();
- document.addEventListener('wheel', (event) => {
- event.preventDefault(); // 阻止页面滚动
- if (event.deltaY < 0) {
- // 向上滚动:上一张
- currentSlide = (currentSlide - 1 + slides.length) % slides.length;
- } else if (event.deltaY > 0) {
- // 向下滚动:下一张
- currentSlide = (currentSlide + 1) % slides.length;
- }
- updateSlider();
- }, { passive: false }); // 必须设置 passive: false 才能调用 preventDefault
- </script>
- </body>
- </html>
复制代码 工作原理:
- 所有幻灯片绝对定位,垂直堆叠;通过translateY移动当前索引外的幻灯片到可视区外。
- 每次滚轮触发时,更新currentSlide索引,然后调用updateSlider重新计算每个slide的translateY值。
- 注意addEventListener的第三个参数要传入{ passive: false },否则部分浏览器会忽略preventDefault调用。
## 兼容旧浏览器(如IE)
虽然wheel已是标准,但个别老旧环境(IE 11以下)不支持。可以同时监听mousewheel进行兜底,但需处理方向值差异:- document.addEventListener('wheel', handleWheel);
- document.addEventListener('mousewheel', handleWheel); // 兼容IE
- function handleWheel(event) {
- // 标准化deltaY值:wheel事件直接用event.deltaY,mousewheel使用event.wheelDelta且方向相反
- const delta = event.deltaY !== undefined ? event.deltaY : -event.wheelDelta;
- if (delta < 0) {
- console.log('向上滚动');
- } else if (delta > 0) {
- console.log('向下滚动');
- }
- }
复制代码 mousewheel的wheelDelta值与deltaY符号相反(向上为正数,向下为负数),所以取负值统一。实际项目建议只使用wheel,仅当确认需要支持IE时才加入mousewheel。
## 常见应用场景
- 无限滚动加载列表(配合防抖或节流)
- 图片查看器的缩放(结合deltaY绝对值控制缩放比例)
- 全屏幻灯片或轮播图的手动翻页
- 自定义平滑滚动视差效果
## 注意事项
- wheel事件会频繁触发,如果回调中有性能消耗大的操作(如DOM操作、网络请求),建议加上throttle或debounce。
- 在移动设备上,wheel事件通常由触摸板滑动触发,deltaY数值单位是像素,但不同浏览器/设备可能不一致,建议只关心方向而非具体数值。
- 大多数现代浏览器支持wheel,无需额外polyfill。
以上便是JavaScript监听鼠标滚轮方向的标准实现,通过wheel事件和deltaY属性即可简洁地判断上下滚动,配合preventDefault可实现完全自定义的滚动交互。 |