【问题标题】:How to overwrite event listener within prototype?如何覆盖原型中的事件监听器?
【发布时间】:2016-05-15 21:04:06
【问题描述】:

我正在尝试实现两种方法:启动和停止。问题是,停止似乎不起作用。

const MyObj = function(x) {
    this.x = x;
};
MyObj.prototype.start = function(el) {
    el.onclick = (function() {
        console.log(this.x);
    }).bind(this);
};
MyObj.prototype.stop = function(el) {
    el.onclick = null;
};

const obj = new MyObj("x");
document.getElementById("checkbox").onchange = function() {
    if (this.value) {
        obj.start(document.body);
    }
    else {
        obj.stop(document.body);
    }
};

我尝试过""function(){} 而不是null,但它们也没有效果。如果我在浏览器控制台中设置onclick 事件,在我调用start 之后,它会起作用。

我该如何解决?

【问题讨论】:

  • 请附上minimal reproducible example。您发布的代码无法正确说明您的问题。
  • Your code works。但是这种方法没有意义。
  • 是的,我的错,我在使用复选框时不小心将this.value 放入了 if 调用启动/停止而不是 this.checked

标签: javascript event-handling prototype event-listener dom-events


【解决方案1】:

obj.stop(document.body) 永远不会运行,因为this.value 始终是true。你要找的是this.checked

固定代码:

const MyObj = function(x) {
    this.x = x;
};
MyObj.prototype.start = function(el) {
    el.onclick = (function() {
        console.log(this.x);
    }).bind(this);
};
MyObj.prototype.stop = function(el) {
    el.onclick = null;
};

const obj = new MyObj("x");
document.getElementById("checkbox").onchange = function() {
    if (this.checked) {
        obj.start(document.body);
    } else {
        obj.stop(document.body);
    }
};

另请参阅this Fiddle 以获取演示。

【讨论】:

    【解决方案2】:

    使用addEventListenerremoveEventListener

    el.addEventListener("click", someHandler);
    // later...
    el.removeEventListener('click', someHandler);
    

    注意someHandler 必须是同一个对象,两次。不要使用内联函数。

    【讨论】:

    • 我想过,但我不能使用它,因为我使用的是构造函数中的值。我已经更新了我的问题。
    • 这是更好的做法,但不能解决(不存在的)问题
    【解决方案3】:



    我制作了自己的事件处理程序版本:

    var EventHandler = function(){}
    EventHandler.prototype.events = [];
    EventHandler.prototype.functions = [];
    EventHandler.prototype.addEventListener = function(e,f,obj)   // start
    {
        if (obj === undefined) obj = window;
        this.events.push(e);
        this.functions.push(f);
        obj.addEventListener(e,f);
    };
    EventHandler.prototype.removeEventListener = function(e,obj)   // stop
    {
        if (obj === undefined) obj = window;
        var i = this.events.indexOf(event);
        if (i === -1)
        {
            return;
        }
        obj.removeEventListener(event,this.functions[i]);
        this.events.splice(i,1);
        this.functions.splice(i,1);
        //this.removeEventListener(e,obj);      // to remove multiple events of the same type
    }
    

    您遇到的问题是,只有在它运行 start 方法时,它才会真正添加 onclick 侦听器。

    const MyObj = function(x) {
        this.x = x;
    };
    MyObj.prototype.start = function(el)
    {
        var self = this;
        el.addEventListener("click",function()
        {
            console.log(self.x);
        });
        console.log("started");
        console.log(el);
    };
    MyObj.prototype.stop = function(el) {
        var self = this;
        el.removeEventListener("click",function()
        {
            console.log(self.x);
        });
        console.log("stopped");
    };
    
    var test = new MyObj(54);
    test.start(document.getElementById("thing"));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-04-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-18
      • 1970-01-01
      相关资源
      最近更新 更多