求助:jQuery鼠标滚轮横竖滚动切换在Firefox与Safari中失效
解决跨浏览器竖向/横向滚动切换的兼容问题
我来帮你搞定这个跨浏览器的滚动切换兼容问题~先看看你的原实现代码和对应的滚动逻辑:
原实现代码
scrollVert(); var scrollLeft=0; function scrollVert() { $('html, body, *').off('mousewheel').mousewheel(function(e, delta) { this.scrollTop -= (delta * 40); e.preventDefault(); setTimeout(function() { if ($(window).scrollTop() + $(window).height() == $(document).height()) scrollHoriz(); }, 0) }); } function scrollHoriz() { $('html, body, *').off('mousewheel').mousewheel(function(e, delta) { this.scrollLeft -= (delta * 40); e.preventDefault(); scrollLeft=this.scrollLeft setTimeout(function() { if (scrollLeft == 0) scrollVert(); }, 0) }); }
滚动逻辑示意图

问题根源分析
你遇到的跨浏览器异常,主要是这两个原因:
- Firefox适配问题:Firefox对
$(document).height()的计算逻辑和Chrome有差异,且原生不支持mousewheel事件(需要用DOMMouseScroll替代),加上你绑定/解绑事件的范围太宽泛,容易导致事件失效。 - Safari精度问题:Safari中
scrollLeft的取值可能因为浮点精度出现类似0.0000001的极小值,直接判断scrollLeft == 0会触发失败,同样事件范围过广也会影响切换逻辑。
修复后的兼容代码
// 初始化竖向滚动 scrollVert(); // 用更精准的变量存储横向滚动位置 let currentScrollLeft = 0; function scrollVert() { // 仅给window绑定事件,避免干扰页面其他可滚动元素 $(window).off('mousewheel DOMMouseScroll').on('mousewheel DOMMouseScroll', function(e) { // 兼容Firefox的滚动事件参数 const delta = e.originalEvent.detail ? -e.originalEvent.detail : e.originalEvent.wheelDelta / 120; const newScrollTop = $(this).scrollTop() - (delta * 40); $(this).scrollTop(newScrollTop); e.preventDefault(); setTimeout(() => { // 用模糊判断替代严格相等,解决浏览器计算精度问题 const isBottom = $(window).scrollTop() + $(window).innerHeight() >= $(document).height() - 1; if (isBottom) { scrollHoriz(); } }, 0); }); } function scrollHoriz() { $(window).off('mousewheel DOMMouseScroll').on('mousewheel DOMMouseScroll', function(e) { const delta = e.originalEvent.detail ? -e.originalEvent.detail : e.originalEvent.wheelDelta / 120; currentScrollLeft = $(this).scrollLeft() - (delta * 40); // 限制横向滚动范围,避免超出左边界 currentScrollLeft = Math.max(0, currentScrollLeft); $(this).scrollLeft(currentScrollLeft); e.preventDefault(); setTimeout(() => { // 模糊判断解决Safari的浮点精度问题 if (currentScrollLeft <= 1) { scrollVert(); } }, 0); }); }
关键改动说明
- 缩小事件绑定范围:仅给
window绑定滚动事件,确保事件解绑更彻底,同时避免干扰页面内其他可滚动元素。 - 兼容Firefox事件:添加
DOMMouseScroll事件处理,适配Firefox的滚动参数逻辑。 - 优化滚动边界判断:用
>= $(document).height() - 1替代严格相等,避免浏览器计算精度导致的判断失效。 - 修复Safari精度问题:用
currentScrollLeft <= 1替代严格等于0,解决浮点数值导致的切换失败。 - 限制滚动范围:给横向滚动值加上
Math.max(0, ...),防止滚出左边界。
这样修改后,就能在Chrome、Firefox和Safari中都稳定实现竖向/横向滚动的切换功能啦~
内容的提问来源于stack exchange,提问作者Jess Cauchi
相关产品推荐
相关产品推荐

