Mac系统及触控板下鼠标滚轮控制Slider滑动异常的修复方案咨询
问题修复方案
核心问题原因
- Mac触控板/妙控鼠标的滚轮事件为连续高频触发,单次滑动操作会触发数十次事件,直接绑定逻辑会导致反复调用轮播切换方法
- 原有逻辑缺少状态锁,轮播动画执行过程中仍会响应新的滚动事件,造成切换错乱
- 未设置滚动阈值,微小的滚动幅度也会触发切换,误触概率高
- 仅绑定了非标准的
mousewheel事件,存在浏览器兼容问题
修复方案
采用节流+状态锁+滚动阈值的组合方案修复,修复后代码如下:
// 新增全局状态变量 let isScrolling = false; // 滚动切换锁,动画过程中为true let deltaCount = 0; // 累计滚动量 const SCROLL_THRESHOLD = 50; // 触发切换的滚动阈值,可根据实际效果调整 const LOCK_DURATION = 800; // 锁定时长,和轮播切换动画时长保持一致即可 // 同时兼容mousewheel、标准wheel和Firefox的DOMMouseScroll事件 $('#body').on('mousewheel wheel DOMMouseScroll', function (event) { event.preventDefault(); // 阻止默认页面滚动,不需要可删除本行 // 处于锁定状态时直接返回 if (isScrolling) return; // 兼容不同浏览器的滚动差值获取 const originalEvent = event.originalEvent; let deltaY = 0; if (originalEvent.wheelDeltaY) { deltaY = originalEvent.wheelDeltaY; } else if (originalEvent.deltaY) { deltaY = -originalEvent.deltaY * 3; // 标准wheel事件差值适配 } else if (originalEvent.detail) { deltaY = -originalEvent.detail * 30; // Firefox兼容 } deltaCount += deltaY; // 累计滚动量未达阈值不触发切换 if (Math.abs(deltaCount) < SCROLL_THRESHOLD) return; const scrolledUp = deltaY < 0; const scrolledDown = deltaY > 0; // 触发切换前加锁 isScrolling = true; deltaCount = 0; // 重置累计滚动量 if (scrolledDown) { if (swiper_color.activeIndex > 2) { goTop(); activeIndexToTwo(); } else { swiper_color.slidePrev(); swiper_image.slidePrev(); swiper_desc.slidePrev(); swiper_title.slidePrev(); swiper_jar.slidePrev(); } } if (scrolledUp) { if (swiper_color.activeIndex < 2) { swiper_color.slideNext(); swiper_image.slideNext(); swiper_desc.slideNext(); swiper_title.slideNext(); swiper_jar.slideNext(); } else { checkscroll(); } } // 锁定时长结束后解锁 setTimeout(() => { isScrolling = false; }, LOCK_DURATION); });
参数调整说明
SCROLL_THRESHOLD:数值越大越不容易触发切换,可根据触控板的灵敏度调整,推荐范围30~100LOCK_DURATION:需要和轮播组件切换动画的时长保持一致,比如动画是600ms就设为600,避免动画未结束就触发下一次切换- 如果不需要阻止页面默认滚动,删除
event.preventDefault()即可
内容的提问来源于stack exchange,提问作者SorryBaby
相关产品推荐
相关产品推荐

