将其用加入结合删除事件侦听器(Removing event listener which was a

2019-06-17 11:41发布

在JavaScript中,什么是去除使用绑定为一个事件侦听器附加功能的最佳方法()?

(function(){

    // constructor
    MyClass = function() {
        this.myButton = document.getElementById("myButtonID");
        this.myButton.addEventListener("click", this.clickListener.bind(this));
    };

    MyClass.prototype.clickListener = function(event) {
        console.log(this); // must be MyClass
    };

    // public method
    MyClass.prototype.disableButton = function() {
        this.myButton.removeEventListener("click", ___________);
    };

})();

我能想到的唯一的办法就是跟踪与绑定添加每一位聆听者的。

上面的例子中使用这种方法:

(function(){

    // constructor
    MyClass = function() {
        this.myButton = document.getElementById("myButtonID");
        this.clickListenerBind = this.clickListener.bind(this);
        this.myButton.addEventListener("click", this.clickListenerBind);
    };

    MyClass.prototype.clickListener = function(event) {
        console.log(this); // must be MyClass
    };

    // public method
    MyClass.prototype.disableButton = function() {
        this.myButton.removeEventListener("click", this.clickListenerBind);
    };

})();

是否有更好的方式来做到这一点?

Answer 1:

虽然什么@machineghost说的是真的,那事件,并移除同样的方法,公式的缺失的部分是这样的:

之后创建一个新的函数参考.bind()被调用!

见不绑定()改变功能引用? | 如何永久设置?

因此,添加或删除,分配参照变量:

var x = this.myListener.bind(this);
Toolbox.addListener(window, 'scroll', x);
Toolbox.removeListener(window, 'scroll', x);

这按预期工作对我来说。



Answer 2:

对于那些在注册/删除组件做出反应/从通量店,下面添加到您的组件的构造线的听众谁拥有这个问题:

 class App extends React.Component { constructor(props){ super(props); // it's a trick! needed in order to overcome the remove event listener this.onChange = this.onChange.bind(this); } // then as regular... componentDidMount (){ AppStore.addChangeListener(this.onChange); } componentWillUnmount (){ AppStore.removeChangeListener(this.onChange); } onChange () { let state = AppStore.getState(); this.setState(state); } render() { // ... } } 



Answer 3:

不要紧,你是否使用绑定功能或没有; 你删除它以同样的方式与任何其他事件处理程序。 如果你的问题是绑定的版本是其独特的功能,你可以跟踪绑定版本,或者使用removeEventListener不采取特定处理器(签名虽然当然,将删除相同的其他事件处理程序类型)。

(作为一个方面说明, addEventListener不会在所有的浏览器。你真的应该使用一个库如jQuery做你的事件挂接起坐在一个跨浏览器的方式为您另外,jQuery有命名空间的事件,的概念,让你绑定到“click.foo”;当你想删除你可以告诉jQuery的“删除所有富事件”,而不知道具体的处理程序或删除其他处理的事件)



Answer 4:

jQuery的解决方案:

let object = new ClassName();
let $elem = $('selector');

$elem.on('click', $.proxy(object.method, object));

$elem.off('click', $.proxy(object.method, object));


Answer 5:

这里是解决方案:

var o = {
  list: [1, 2, 3, 4],
  add: function () {
    var b = document.getElementsByTagName('body')[0];
    b.addEventListener('click', this._onClick());

  },
  remove: function () {
    var b = document.getElementsByTagName('body')[0];
    b.removeEventListener('click', this._onClick());
  },
  _onClick: function () {
    this.clickFn = this.clickFn || this._showLog.bind(this);
    return this.clickFn;
  },
  _showLog: function (e) {
    console.log('click', this.list, e);
  }
};


// Example to test the solution
o.add();

setTimeout(function () {
  console.log('setTimeout');
  o.remove();
}, 5000);


Answer 6:

我们有这个问题,我们不能更改库。 办公面料UI,这意味着我们无法改变添加事件处理程序的方式。 我们解决它的方法是覆盖addEventListenerEventTarget的原型。

这将添加一个新功能上的对象element.removeAllEventListers("click")

(原帖: 取下布对话框覆盖Click处理程序 )

        <script>
            (function () {
                "use strict";

                var f = EventTarget.prototype.addEventListener;

                EventTarget.prototype.addEventListener = function (type, fn, capture) {
                    this.f = f;
                    this._eventHandlers = this._eventHandlers || {};
                    this._eventHandlers[type] = this._eventHandlers[type] || [];
                    this._eventHandlers[type].push([fn, capture]);
                    this.f(type, fn, capture);
                }

                EventTarget.prototype.removeAllEventListeners = function (type) {
                    this._eventHandlers = this._eventHandlers || {};
                    if (type in this._eventHandlers) {
                        var eventHandlers = this._eventHandlers[type];
                        for (var i = eventHandlers.length; i--;) {
                            var handler = eventHandlers[i];
                            this.removeEventListener(type, handler[0], handler[1]);
                        }
                    }
                }

                EventTarget.prototype.getAllEventListeners = function (type) {
                    this._eventHandlers = this._eventHandlers || {};
                    this._eventHandlers[type] = this._eventHandlers[type] || [];
                    return this._eventHandlers[type];
                }

            })();
        </script>


Answer 7:

如果你想使用的“onClick”,如上面所说,你可以试试这个:

(function(){
    var singleton = {};

    singleton = new function() {
        this.myButton = document.getElementById("myButtonID");

        this.myButton.onclick = function() {
            singleton.clickListener();
        };
    }

    singleton.clickListener = function() {
        console.log(this); // I also know who I am
    };

    // public function
    singleton.disableButton = function() {
        this.myButton.onclick = "";
    };
})();

我希望它能帮助。



Answer 8:

它已经一段时间,但MDN对这个超级解释。 这让我比这里的东西更多。

MDN :: EventTarget.addEventListener -的“本”的处理程序中的价值

它给到的handleEvent函数的理想替代品。

这是有和没有绑定的示例:

var Something = function(element) {
  this.name = 'Something Good';
  this.onclick1 = function(event) {
    console.log(this.name); // undefined, as this is the element
  };
  this.onclick2 = function(event) {
    console.log(this.name); // 'Something Good', as this is the binded Something object
  };
  element.addEventListener('click', this.onclick1, false);
  element.addEventListener('click', this.onclick2.bind(this), false); // Trick
}

在上面的例子中的一个问题是,你不能用绑定删除侦听。 另一种解决方案是使用所谓的handleEvent一个特殊的函数来捕捉任何事件:



文章来源: Removing event listener which was added with bind