lit-element项目中removeEventListener移除scroll事件不生效问题
问题根因
核心问题是你在stateChanged回调中重复创建了ScrollManager实例,导致旧的scroll监听残留没有被移除:
- 当
isEditMode为true的状态下如果stateChanged多次触发,每次都会new一个新的ScrollManager实例,覆盖this._scrollManager中保存的旧实例 - 后续调用
unsubscribeDomEvents时,只会移除最后一个实例绑定的监听,之前所有旧实例绑定的scroll监听没有被移除,依然会触发_onScroll打印日志
修复方案
1. 组件侧新增实例创建前的旧实例销毁逻辑
在创建新的ScrollManager前先销毁已存在的旧实例,卸载后将实例变量置空,避免残留:
stateChanged(state: IState): void { ... this.isEditMode = state.modes.isEditMode; if (this.isEditMode) { // 先销毁已存在的旧实例,避免重复绑定监听 this._scrollManager?.unsubscribeDomEvents(); this._scrollManager = new ScrollManager({ container: this.container }) .onScrollDown(this.onScrollDown.bind(this)); } else { this._scrollManager?.unsubscribeDomEvents(); // 卸载后置空实例变量 this._scrollManager = null; } this.requestUpdate(); }
2. 可选优化:修正ScrollManager回调存储类型
你当前用数组_callbacks存储字符串键的回调,不符合数组的设计语义,建议改为对象存储:
// 原代码:private _callbacks = []; // 修改为 private _callbacks: Record<string, Function> = {};
3. 可选优化:组件卸载时主动销毁监听
在lit组件的disconnectedCallback生命周期中补充监听销毁逻辑,避免组件卸载后监听残留:
override disconnectedCallback() { super.disconnectedCallback(); this._scrollManager?.unsubscribeDomEvents(); this._scrollManager = null; }
内容的提问来源于stack exchange,提问作者MarkMark
相关产品推荐
相关产品推荐

