【问题标题】:Remove nested event listeners in JavaScript classes移除 JavaScript 类中的嵌套事件监听器
【发布时间】:2019-11-25 22:16:36
【问题描述】:

我有一个事件侦听器,该侦听器由另一个事件侦听器添加,该事件侦听器由类中的函数添加。我希望这个事件监听器执行一次,然后自行移除。

为了简化问题,假设我有以下 HTML 代码:

<div class="container">
<div class="redDiv">some html</div>
<div class="blueDiv">some html</div>
</div>

以及以下 JavaScript 代码:

class Test {

    constructor(_container){
      this.container = _container;
    }

    somefunc(){
      // some code here
      this.removeEventListener('click',somefunc);
    }

    start(){
      var container = this.container;    
      container.querySelector('.redDiv').addEventListener('click',function(){
        container.querySelector('.blueDiv').addEventListener('click',somefunc);
      });
    } 
  }



let tester = new Test(document.querySelector('.container'));
tester.start();

我遇到的第一个问题是somefunc 没有在第二个事件监听器的范围内定义。我发现的唯一解决方案是在start 函数中创建一个新变量fnc 并将somefunc 分配给它,然后调用fnc 而不是somefunc

这使得添加事件侦听器工作并且代码按预期运行,但是当执行somefunc() 时,删除事件侦听器不起作用,因为somefunc 在此范围内未定义。

我尝试通过将代码更改为此将somefunc 传递到此范围:

class Test {

    constructor(_container){
      this.container = _container;
    }

    somefunc(func){
      return function(){
      // some code here
      this.removeEventListener('click',func);
      }
    }


    start(){
      var fnc = this.somefunc;
      var container = this.container;    
      container.querySelector('.redDiv').addEventListener('click',function(){
        container.querySelector('.blueDiv').addEventListener('click',fnc(fnc));
      });
    } 
  }

let tester = new Test(document.querySelector('.container'));
tester.start();

现在,代码不会产生任何错误,但事件侦听器并未按需要删除。这可能与 JavaScript 分配变量的方式有关,这是我不太了解的主题。但我感兴趣的是如何解决这个问题,并能够在事件监听器执行后移除它。

【问题讨论】:

  • medium.com/beginners-guide-to-mobile-web-development/… 在这篇文章中有你想要的东西。请交叉检查
  • 感谢您的帮助,但由于某种原因,arguments.callee 在类中生成错误,并且 once 参数可以解决此问题,但它不能解决我想删除侦听器的情况从以前的范围或 n 次执行之后。

标签: javascript class removeeventlistener


【解决方案1】:

一种解决方案是使用arrow function 来维护this 的引用...

class Test {

    constructor(_container){
      this.container = _container;
    }

    somefunc(fn){
      console.log('clicked blue div')
      this.container.querySelector('.blueDiv').removeEventListener('click', fn);
    }


    start(){
      var container = this.container;    
      container.querySelector('.redDiv').addEventListener('click',() => {
        console.log('clicked red div')
        // Wrap someFunc in an arrow function to have "this" inside somefunc 
        // reference this class. 
        const func = () => this.somefunc(func);
        container.querySelector('.blueDiv').addEventListener('click', func);
      });
    } 
  }

let tester = new Test(document.querySelector('.container'));
tester.start();

StackBlitz Example

【讨论】:

  • 谢谢,问题解决了。我还在学习 JavaScript,以前从未使用过箭头函数,实际上从未理解过它们。我认为是时候学习它们了。
最近更新 更多