【问题标题】:Why can't I addEventListener after removeEventListner has been used?为什么使用 removeEventListner 后不能 addEventListener?
【发布时间】:2023-04-07 16:31:01
【问题描述】:

mdn 我读到“一个 EventListener 在被删除后永远不能被调用”,但我认为这并不意味着你不能再次添加它(这没有意义)。这是我正在做的一个简化示例,所以如果示例中有一个小的语法错误,它可以被忽略(除非语法错误必须是问题)。

function OhYeah(el){
    this.stuff = [];

    this.stuff.push(new Obj(el));
}

OhYeah.prototype = {
    removeStuff: function() {
        for(var i = 0; i < this.stuff.length; i++){
            this.stuff[i].selfDestruct(); // removes listener
        } 

        this.stuff = [];
    },

    addStuff: function(el) {
        this.stuff.push(new Obj(el)); // should add listener on creation of Obj
    }
}

function Obj(el) {
    // some other properties not shown that can be different even if the same "el" is used to create a new Obj

    this.domOBJ = document.getElementById(el);

    this.domOBJ.addEventListener("input", this, false);
}


Obj.prototype = {
    ...

    handleEvent: function(){
        ...
    },
    selfDestruct: function() {
        this.domOBJ.removeEventListener("input", this, false);
    }
}

var obj = new OhYeah("demo"); // adds listener successfully

obj.removeStuff(); // removes listener successfully
obj.addStuff("demo") // you would think this would add the listener, BUT it does NOT

【问题讨论】:

  • .addEventListener("input", this
  • @epascarello — 它之所以有效,是因为 Obj 在其原型上有一个 handleEvent 方法。处理程序将在处理事件时调用它,请参阅 W3C DOM 2 Events EventListener interface 的规范,在 DOM 3 Events spec 中更新。
  • MDN 不再说“…被删除后永远无法调用”。 ;-)

标签: javascript addeventlistener dom-events


【解决方案1】:

原始代码有一些语法错误。既然你已经修复了这些,但显然代码不起作用,那么它必须在其他地方,以下工作:

<input id="demo">

<script>
function OhYeah(el){
    this.stuff = [];
    this.stuff.push(new Obj(el));
}

OhYeah.prototype = {
    removeStuff: function() {
        for(var i = 0; i < this.stuff.length; i++){
            this.stuff[i].selfDestruct(); // removes listener
        } 
        this.stuff = [];
    },

    addStuff: function(el) {
        this.stuff.push(new Obj(el)); // adds listener on creation of Obj
    }
}

function Obj(el) {
    this.domOBJ = document.getElementById(el);
    this.domOBJ.addEventListener("input", this, false);
}

Obj.prototype = {
    handleEvent: function(){
          console.log('input...');
        }
    },
    selfDestruct: function() {
        this.domOBJ.removeEventListener("input", this, false);
    }
  }

  var obj = new OhYeah("demo"); // adds listener successfully

  obj.removeStuff();   // removes listener successfully
  obj.addStuff("demo") // adds  listener successfully

</script>

这是一个jsfiddle,表明它有效。

请注意,这是因为 Obj.prototypehandleEvent 属性而起作用的。见W3C DOM 3 Events Specification, eventListener interface

【讨论】:

  • 但是将具有handleEvent 属性的对象传递给addEventListener 函数不是正确的吗?请参阅developer.mozilla.org/en-US/docs/Web/API/… 上有关使用handleEvent 的部分
  • 好的,现在我明白你要做什么了。给我一些时间。
  • 另请注意,添加侦听器和删除两者都是第一次工作,因此使用handleEvent 作为Obj 的属性,然后传递事件侦听器this 确实有效。
  • @cojomojo——我已经粘贴了工作代码。注释掉最后两行,然后一次显示一行,表明它们可以添加、删除,然后再次添加侦听器。顺便说一句,我不知道你可以用原生对象做到这一点,很酷。 ;-)
  • 我自己也是不久前才学会的。好的,它的工作。必须查看我的实际代码并检查差异。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-09-21
  • 1970-01-01
  • 2023-01-29
  • 2013-06-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多