Search code examples
javascriptlistenerdom-events

Remove a listener that gets bound dynamically to undetermined elements?


I have the following code and I would need help to remove all my listeners, including the func listener which may be applied to multiple elements :

var associateListener = function(event)
{
    var element = event.srcElement||event.target;
    element.addEventListener("click", func, false);
    element.addEventListener("mousedown", func, false);
    element.addEventListener("mouseup", func, false);    
};
var addListeners = function(win)
{
    win.document.addEventListener("click", associateListener, true);
    win.document.addEventListener("mousedown", associateListener, true);
    win.document.addEventListener("mouseup", associateListener, true);
};
var deleteListeners = function(win)
{
    ??
};

I tried to put :

win.document.removeEventListener("click", associateListener, true);
win.document.removeEventListener("mousedown", associateListener, true);
win.document.removeEventListener("mouseup", associateListener, true);

but it didn't remove the listeners associated to the elements. I'd like to remove also these listeners.


Solution

  • This should work for what you want to do: http://jsfiddle.net/7jQJj/3/

    var elesBound = []
    var func = function () {
        console.log("func from ele: "+this.tagName+"(id: "+this.id+")");
    }
    var associateListener = function (event) {
        console.log("associateListener");
        var element = event.srcElement || event.target;
        element.addEventListener("click", func, false);
        element.addEventListener("mousedown", func, false);
        element.addEventListener("mouseup", func, false);
        elesBound.push(element);
    };
    var addListeners = function (win) {
        console.log("addListeners");
        win.document.addEventListener("click", associateListener, true);
        win.document.addEventListener("mousedown", associateListener, true);
        win.document.addEventListener("mouseup", associateListener, true);
    };
    var deleteListeners = function (win) {
        console.log("deleteListeners");
        win.document.removeEventListener("click", associateListener, true);
        win.document.removeEventListener("mousedown", associateListener, true);
        win.document.removeEventListener("mouseup", associateListener, true);
        for (var i = 0; i < elesBound.length; i++) {
            elesBound[i].removeEventListener("click", func, false);
            elesBound[i].removeEventListener("mousedown", func, false);
            elesBound[i].removeEventListener("mouseup", func, false);
        }
        elesBound = [];
    };
    document.getElementById("removeListeners").addEventListener("click", function () {
        deleteListeners(window);
    });
    addListeners(window);
    

    Basically I kept a list that keeps track of which elements are bound to func, then unbind them all on deleteListeners.

    Example of what you'll see in the console:

    addListeners
    associateListener 
    func from ele: DIV(id: d2) 
    associateListener 
    func from ele: DIV(id: d2) 
    associateListener 
    func from ele: DIV(id: d2) 
    associateListener 
    func from ele: DIV(id: d1) 
    associateListener 
    func from ele: DIV(id: d1) 
    associateListener 
    func from ele: DIV(id: d1) 
    associateListener 
    func from ele: BUTTON(id: removeListeners) 
    associateListener 
    func from ele: BUTTON(id: removeListeners) 
    associateListener 
    deleteListeners 
    

    After this (when deleteListeners is called), you can click anywhere and your associateListener and func will not be called as all the event listeners will be removed.