Breimer
Breimer

Reputation: 585

removeEventListener of Anonymous function javaScript

how can i remove this event listener I have tried but below code and it does not seam to bare any fruit

class Tag {
  constructor(name){
      this.tag = document.createElement(name);
  }
      removeEvent(e,func){
      this.tag.removeEventListener(e,func,false);
  }
      addEvent(e,func) {
      this.tag.addEventListener(e,func,false);
  }

}

let tag = new Tag();
tag.addEvent('click',(e)=> {
   console.log('something');
});

How do I get the removeEvent to work? please help I specifically need how to reference the anonymous function since this works.

 function handler(e){
     // code for event
 }

 tag.addEventListener('click',handler,false);  
 tag.removeEventlistener('click',handler,false);

I have tried adding

  removeEvent(e,func) {
      func.ref = function (){
          return arguments.callee;
      }

      this.tag.removeEventListener(e,func.ref,false);

  }

Just doesn't work given now we would be referring to func.ref as the function reference;

Upvotes: 3

Views: 8457

Answers (4)

Nicolas.l
Nicolas.l

Reputation: 21

Simple way to remove anonymous event listener

A nice and simple way I found to remove eventListener that uses anonymous functions is to add these two functions into your code:

let events = new Map();
function addListener(element, event, callback, id) {
    events.set(id, callback);
    element.addEventListener(event, callback);
}

function removeListener(element, event, id) {
    element.removeEventListener(event, events.get(id));
    events.delete(id);
}

Anonymous function are great to keep the this context, and didn't found a good way to have both this, and the ability to remove the eventListener.

Example

let events = new Map();

function addListener(element, event, id, callback) {
  events.set(id, callback);
  element.addEventListener(event, callback);
}

function removeListener(element, event, id) {
  element.removeEventListener(event, events.get(id));
  events.delete(id);
}


let btn = document.getElementById('btn');
let cpt = 1;
addListener(btn, 'click', 'btnClick', e => {
  btn.innerHTML = `x${++cpt}`;

  if (cpt === 3) {
    removeListener(btn, 'click', 'btnClick');
  }
});
<button id="btn">x1</button>

Upvotes: 2

ow3n
ow3n

Reputation: 6597

I had the same problem in an extension I was writing. I solved this by adding a new listener that caught / stopped all propagation of the event before it reached the listener / function I wanted to remove.

window.addEventListener(type, function (event) {
    event.stopPropagation();
}, true);

Credit: StackOverflow

Upvotes: 3

quirimmo
quirimmo

Reputation: 9988

There is not a way unfortunately to remove anonymous functions attached as listeners.

You can use a little workaround storing every time the functions you pass in and keeping track of all the events, then use the "cached" event listeners for retrieving them and detach the events.

Here a draft of an example:

var events = [];

function storeEvent(id, fn, useCaptureMode, event) {
	var e = findStoredEvent(id, event, useCaptureMode);
  if (!e) {
  	events.push({id, fn, useCaptureMode, event});
  }
}

function findStoredEvent(id, event, useCaptureMode) {
	return events.find(el => el.id === id && el.event === event && el.useCaptureMode === el.useCaptureMode);
}

document.getElementById("test").addEventListener('click', function() {
	storeEvent(this.id, arguments.callee, false, 'click');
	console.log('test');
}, false);

function detachEvent() {
	var e = findStoredEvent('test', 'click', false);
  if (e) {
		document.getElementById("test").removeEventListener(e.event, e.fn, e.useCaptureMode);
    events.splice(events.findIndex(el => el === e), 1);
  } 
}
<button id="test">
  Test
</button>
<button id="remove" onclick="detachEvent()">
  Remove Event
</button>

I hope it helps

Upvotes: 0

Scott Marcus
Scott Marcus

Reputation: 65796

Anonymous functions can't be removed because they are not stored with an identifier that is accessible to your code. That's why they call them "anonymous" and that's one of the down sides to using them. Another down side is not being able to write unit tests directly for them. The up side of them is that because they are not stored, a bit of memory is saved. Also, JavaScript, being a functional programming language, allows for anonymous functions to be passed quite easily as data (although you can certainly pass named function references).

Upvotes: 1

Related Questions