Javascript 调整大小后删除eventListeners

Javascript 调整大小后删除eventListeners,javascript,Javascript,调整浏览器大小后,我需要删除事件侦听器。我试过这样的方法: window.addEventListener('resize', () => { const bp = this.breakpointInit.getValue(); if (bp === 'mobile') { this.toggleMobile(); } else { this.toggleDesktop(); } }); }

调整浏览器大小后,我需要删除事件侦听器。我试过这样的方法:

  window.addEventListener('resize', () => {
      const bp = this.breakpointInit.getValue();

      if (bp === 'mobile') {
        this.toggleMobile();
      } else {
        this.toggleDesktop();
      }
    });
  }

  toggleMobile() {
    Array.prototype.forEach.call(this.elements, (el) => {
      const activeClass = `${el.classList[0]}--active`;

      el.addEventListener('touchstart', (e) => {
        this.switchClass(e, el, activeClass);
      });

      el.removeEventListener('mouseenter', (e) => {
        this.switchClass(e, el, activeClass);
      });

      el.removeEventListener('mouseleave', (e) => {
        this.switchClass(e, el, activeClass);
      });
    });
  }

  toggleDesktop() {
    Array.prototype.forEach.call(this.elements, (el) => {
      const activeClass = `${el.classList[0]}--active`;

      el.addEventListener('click', (e) => {
        this.switchClass(e, el, activeClass);
      });

      el.addEventListener('mouseenter', (e) => {
        this.switchClass(e, el, activeClass);
      });

      el.addEventListener('mouseleave', (e) => {
        this.switchClass(e, el, activeClass);
      });

      el.removeEventListener('touchstart', (e) => {
        this.switchClass(e, el, activeClass);
      });
    });
  }
let me = this;

//this probably won't work exactly as-is, but you should get the idea
touchStartHandler(e) {
    me.switchClass(e, el, activeClass);
}

el.addEventListener('touchstart', touchStartHandler);

//...

el.removeEventListener('touchstart', touchStartHandler);

所述功能在需要时触发,但事件监听器会继续执行。我做错了什么?

您正在分配匿名函数,这些函数实际上无法删除

试着这样做:

  window.addEventListener('resize', () => {
      const bp = this.breakpointInit.getValue();

      if (bp === 'mobile') {
        this.toggleMobile();
      } else {
        this.toggleDesktop();
      }
    });
  }

  toggleMobile() {
    Array.prototype.forEach.call(this.elements, (el) => {
      const activeClass = `${el.classList[0]}--active`;

      el.addEventListener('touchstart', (e) => {
        this.switchClass(e, el, activeClass);
      });

      el.removeEventListener('mouseenter', (e) => {
        this.switchClass(e, el, activeClass);
      });

      el.removeEventListener('mouseleave', (e) => {
        this.switchClass(e, el, activeClass);
      });
    });
  }

  toggleDesktop() {
    Array.prototype.forEach.call(this.elements, (el) => {
      const activeClass = `${el.classList[0]}--active`;

      el.addEventListener('click', (e) => {
        this.switchClass(e, el, activeClass);
      });

      el.addEventListener('mouseenter', (e) => {
        this.switchClass(e, el, activeClass);
      });

      el.addEventListener('mouseleave', (e) => {
        this.switchClass(e, el, activeClass);
      });

      el.removeEventListener('touchstart', (e) => {
        this.switchClass(e, el, activeClass);
      });
    });
  }
let me = this;

//this probably won't work exactly as-is, but you should get the idea
touchStartHandler(e) {
    me.switchClass(e, el, activeClass);
}

el.addEventListener('touchstart', touchStartHandler);

//...

el.removeEventListener('touchstart', touchStartHandler);

拥有命名函数允许您随时添加和删除内容,因为您有对原始处理函数的引用。

每次声明函数时,您都在创建一个全新的函数实例。这就是为什么无法将其从事件侦听器中删除。该函数的实例一开始就不存在。只要引用同一个已声明的函数实例,它就可以工作。例如(使用数组):


这使用数组来跟踪函数实例。请注意,它们都是相同的代码,但在技术上是不同的实例。如果它们都将保持不变,那么您实际上可以对所有事件侦听器只使用一个实例。

而且它的副本实际上不必命名。例如,一个匿名函数可以放置在数组中,并由
.addEventListener
引用。从该引用中移除EventListener
。只要你添加和删除完全相同的函数实例,就可以了。@JonathanGray你能解释一下你说的话吗,也许可以作为一个答案?@ArthurKay谢谢你提供的信息,但是范围在这里是个问题,我不知道如何克服它。还有什么我能做的吗?@TomekBuszewskiI更新了我的示例,以帮助您理解范围。您只需要在命名函数之外引用任何作用域(
this
el
activeClass
,等等),但仍然可以访问它。我刚刚意识到,由于
el
不再在作用域中,所以此代码将无法工作。我认为不应该在每个元素上附加事件监听器,而应该在整个文档上进行。我将修改此代码,使其按原样工作。我已进行了修改,使其按原样工作。