Apologies in advance as I have done some searching and this appears to be a fairly common question, but none of the answers I have found quite meet my needs. The closest I was able to find was How do I add and remove an event listener using a function with parameters?, but the answer there involves JQuery and I am trying to find a way to do this in just JS.

I am using anonymous functions to pass parameters through an event trigger which I believe is the correct way to do so. If temp is defined by some calculations based on the state at the time the event is added, I want to add the listener as follows:

item.addEventListener("click", function(){myOnClickFunction(temp)});

However, I want to be able to remove the event dynamically if certain conditions are met.

item.removeEventListener("click", function(){myOnClickFunction(temp)});

This does not work as the inline function is anonymous and cannot be referenced for matching up the event listener (plus temp is likely different anyway). Since temp is calculated at the time of the trigger, I cannot store a reference outside of the anonymous function with something like this:

var listener = function() {
  var temp = calculate(arg1, arg2, event);
  myFunction(temp);
};
window.addEventListener('click', listener, false);

so that I can later call:

window.removeEventListener('click', listener, false);


myOnClickEvent(temp){
  //My code and calculations here
  document.removeEventListener("keypress", arguments.callee);
}

is also not working, although I'm less confident as to how that method is supposed to work.

How can I remove this function dynamically? In some cases, I might be able to refactor my code so that all variables that need to be passed are stored globally and rewritten constantly, but that sounds like messy code. Plus, in some cases the trigger event is one of the arguments that needs to be passed so I don't think I could make that happen. Any ideas?

1 Answers

0
CertainPerformance On Best Solutions

You can create an object, whose properties are the temp values, and whose values are myOnClickFunction bound to that temp. For example:

const boundFns = {};
// acquire temp somehow
const boundFn = () => myOnClickFunction(temp);
boundFns[temp] = boundFn;
item.addEventListener("click", boundFn);

Then, when you need to remove the listener, retrieve the appropriate bound function:

item.removeEventListener("click", boundFns[temp]);

If a temp may be used more than once, check if it exists in boundFns first:

const boundFns = {};
// acquire temp somehow
if (!boundFns[temp]) {
  boundFns[temp] = () => myOnClickFunction(temp);
}
const boundFn = boundFns[temp];
boundFns[temp] = boundFn;
item.addEventListener("click", boundFn);

If temp cannot be be used reliably as a unique object key (for example, if it's an HTMLElement), you can use a Map instead, which is like an object, but whose keys can be anything, not just strings:

const boundFns = new Map();
boundFns.set(temp, boundFn);
// ...
item.removeEventListener("click", boundFns.get(temp));