2

I'm trying to remove an event listener for created span elements where the function called is within a closure. I've tried various methods and none seem to work.

var MyClass = function () {}

MyClass.prototype.addSpan = function (el) {
    var span = document.createElement('span');
    span.innerHTML = "Text here";
    el.appendChild(span);
    span.addEventListener('click', (function (obj) { 
        return function () { 
            obj.removeSpan(); 
        }
    })(this), false);
}

MyClass.prototype.removeSpan = function () {
    alert('removing span');
    this.removeEventListener('click', arguments.callee, false);
    // .... remove span .... 
}

myclass = new MyClass();

myclass.addSpan(document.getElementById('box'));

I've also used

this.removeEventListener('click', (function (obj) { 
    return function () { 
        obj.removeSpan(); 
    }
})(this), false);

in place of this.removeEventListener('click', arguments.callee, false); but had no luck.

Any help is much appreciated!

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Rich
  • 357
  • 4
  • 10
  • Simplify the unnecessary closure: (function (obj) { return function () { obj.removeSpan(); })(this) -> function( obj ) { obj.removeSpan(); } – sergzach Mar 29 '12 at 16:01
  • In your example the obj will refer to the event rather than the class. – Rich Mar 29 '12 at 16:10
  • Why are you trying to call removeSpan from removeEventLister? Your removeEventListener calls removeSpan. It's infinite recursion. – sergzach Mar 29 '12 at 16:13

2 Answers2

4
var MyClass = function () {}
MyClass.prototype.listener=null;
MyClass.prototype.addSpan = function (el) {
    var span = document.createElement('span');
    span.innerHTML = "Text here";
    el.appendChild(span);
    span.addEventListener('click', (function (obj) { 
        return obj.listener = function () { 
            obj.removeSpan(this); // here 'this' refers to 'span'
        }
    })(this), false);
}

MyClass.prototype.removeSpan = function (el) {
    alert('removing span');
    el.removeEventListener('click', this.listener, false);
    // .... remove span .... 
}

myclass = new MyClass();
myclass.addSpan(document.getElementById('box'));

Without a reference of the listener you can't remove it, so I've also added a property (listener) to the MyClass' prototype and then returned the reference as return obj.listener and also you need to pass the object as I've passed it obj.removeSpan(this); and in the removeSpan I've received with el so I could've done el.removeEventListener, hope it helps.

You can also do this

var MyClass = function () {this.listener=null;}

instead of

MyClass.prototype.listener=null;

Here is an example.

The Alpha
  • 143,660
  • 29
  • 287
  • 307
0

Try changing your event handler to this.

span.addEventListener('click', (function (obj) { 

        span.onclick = null;

        return function () { 
            obj.removeSpan(); 
        }
    })(this), false);
KDV
  • 730
  • 1
  • 6
  • 12