You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 20:27:02