调整大小后删除eventListeners

时间:2016-05-13 13:13:24

标签: javascript

我需要在调整浏览器大小后删除我的事件监听器。我试过这样的事情:

  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);
      });
    });
  }

在需要时触发所述函数,但事件监听器被转移。我做错了什么?

2 个答案:

答案 0 :(得分:1)

您正在分配无法真正删除的匿名函数。

尝试这样的事情:

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);

使用命名的函数可以随时添加和删除内容,因为您可以引用原始处理函数。

答案 1 :(得分:0)

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

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

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

  var handlers = [(e) => { // touchstart
        const activeClass = `${el.classList[0]}--active`;
        this.switchClass(e, e.target, activeClass);
      },(e) => { // click
        const activeClass = `${el.classList[0]}--active`;
        this.switchClass(e, e.target, activeClass);
      },(e) => { // mouseenter
        const activeClass = `${el.classList[0]}--active`;
        this.switchClass(e, e.target, activeClass);
      },(e) => { // mouseleave
        const activeClass = `${el.classList[0]}--active`;
        this.switchClass(e, e.target, activeClass);
      }];

  toggleMobile() {
    Array.prototype.forEach.call(this.elements, (el) => {
      el.addEventListener('touchstart', handlers[0]);
      el.removeEventListener('click', handlers[1]);
      el.removeEventListener('mouseenter', handlers[2]);
      el.removeEventListener('mouseleave', handlers[3]);
    });
  }

  toggleDesktop() {
    Array.prototype.forEach.call(this.elements, (el) => {
      el.addEventListener('click', handlers[1]);
      el.addEventListener('mouseenter', handlers[2]);
      el.addEventListener('mouseleave', handlers[3]);
      el.removeEventListener('touchstart', handlers[0]);
    });
  }

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