原生JS实现鼠标滚轮横向滚动:移除事件监听失效问题排查
问题原因与解决方案
核心问题
每次执行wheel函数时,都会重新创建一个全新的scroll函数实例。这就导致:
- 窗口宽度>954时,绑定的是某一个
scroll函数实例; - 窗口缩小后执行
removeEventListener时,你试图移除的是刚生成的新scroll实例——这个实例从未被绑定过,之前绑定的旧实例依然生效,所以滚轮监听没被真正移除,e.preventDefault()还在阻止默认滚动行为。
修复代码
把scroll函数的定义移到wheel函数外部,确保每次添加/移除监听的是同一个函数引用:
// 将scroll函数提取到外部,保证引用唯一不变 var scroll = function( e ) { e.preventDefault(); if ( Math.abs( e.deltaY ) >= Math.abs( e.deltaX ) ) { this.scrollLeft += ( e.deltaY * 10 ); } else { this.scrollLeft -= ( e.deltaX * 10 ); } }; var wheel = function() { var width = window.innerWidth; if ( width > 954 ) { document.documentElement.addEventListener( 'wheel', scroll ); } else { document.documentElement.removeEventListener( 'wheel', scroll ); } }; wheel(); window.addEventListener( 'resize', wheel );
额外优化建议
- 给resize事件添加防抖处理,避免窗口拖动过程中频繁触发
wheel函数:var debounceWheel = function() { clearTimeout( this._timer ); this._timer = setTimeout( wheel, 100 ); }; window.addEventListener( 'resize', debounceWheel ); - 注:
document.documentElement对应HTML元素,和jQuery中的$('html')完全一致,当前场景下无需额外处理document.body。
内容的提问来源于stack exchange,提问作者leemon
相关产品推荐
相关产品推荐

