Javascript removeEventListener not working
Solution 1
This is because that two anonymous functions are completely different functions. Your removeEventListener
's argument is not a reference to the function object that was previously attached.
function foo(event) {
app.addSpot(event.clientX,event.clientY);
app.addFlag = 1;
}
area.addEventListener('click',foo,true);
area.removeEventListener('click',foo,true);
Solution 2
I find that for the windows object, the last param "true" is required. The remove doesn't work if there is no capture flag.
Solution 3
In a React function component, make sure to define the callback with the useCallback(() => {})
hook. If you fail to do this, the callback will be a different one on every re-render and the removeEventListener
method will not work.
const scrollCallback = useCallback(() => { // do sth. });
window.addEventListener("scroll", scrollCallback, true);
window.removeEventListener("scroll", scrollCallback, true);
Solution 4
You are creating two different functions in both calls. So the second function does not relate in any way to the first one and the engine is able to remove the function. Use a common identifier for the function instead.
var handler = function(event) {
app.addSpot(event.clientX,event.clientY);
app.addFlag = 1;
};
area.addEventListener('click', handler,true);
later you can then remove the handler by calling
area.removeEventListener('click', handler,true);
Solution 5
To remove it, store the function in a variable or simply use a named function and pass that function to the removeEventListener
call:
function areaClicked(event) {
app.addSpot(event.clientX, event.clientY);
app.addFlag = 1;
}
area.addEventListener('click', areaClicked, true);
// ...
area.removeEventListener('click', areaClicked, true);
Comments
-
Jinu Joseph Daniel almost 2 years
I have the following code to add eventListener
area.addEventListener('click',function(event) { app.addSpot(event.clientX,event.clientY); app.addFlag = 1; },true);
It is working correctly as expected..Later in another function i tried to remove the event listener using the following code
area.removeEventListener('click',function(event) { app.addSpot(event.clientX,event.clientY); app.addFlag = 1; },true);
But the even listener is not removed..Why is it happening?Is there any problem with my removeEventListener()? Note:Here area is something like document.getElementById('myId')
-
Jinu Joseph Daniel about 12 yearsbut how can i pass arguments(here event ) to that function..That's why i used anonymous function
-
ThiefMaster about 12 yearsIt is passed by the browser. It doesn't matter if you define the function separately or not.
-
NiRUS about 7 years+1 True.
bind(this)
will change the signature. So always assign the function to avar
after bindingthis
to using functionbind
API so that samevar
can be used inremoveListener
. You will see this problem more evident in typescript -
IC_ about 7 yearsThat won't allow you to pass function parameters f.e.
foo(1)
-
David Edwards over 6 yearsI've encountered a problem here. Even if you define an event handler function, save a reference to that function, and then pass that reference to removeEventListener() later, the function isn't removed. Comment's too small to post code in, so if you want code, I'll have to use up an answer box ...
-
David Edwards over 6 yearsAddendum to the above: another interesting phenomenon I've found, is that even if you specify that your event listener is passive, the old one still persists in the chain. Worse still, the old one now becomes a blocking event handler, whilst the new one keeps its passive status. I think an explanation is needed here.
-
VectorVortec over 6 yearsYou should ask a new question. This area answers the OP's question.
-
David Edwards over 6 yearsWARNING: I found out what was wrong with my approach. The removeEventListener() method ONLY works with NAMED FUNCTIONS. It does NOT work with anonymous functions! When I edited the code to take this into account, everything worked as planned. You have to define a NAMED function in your closure, and return a reference to an instance thereof with the parameters passed by the closure. Do this, and removeEventListener() works perfectly.
-
Mave over 5 yearsI ran into this as well. It's nonsense. Had to resort to dirty methods of getting by, ie. keeping track which events should be enabled/disabled in the window object.
-
joseluisq about 5 yearsIf someone use classes try something like
this.onClick = this.onClick.bind(this)
before any listener, thenbtn.addEventListener('click', this.onClick)
, finallybtn.removeEventListener('click', this.onClick)
-
raven-king over 2 years@Herrgott To pass arguments to the handler function you can use currying:
foo = (argumentToPass) => (event) => { doSomething(); }
, thenxyz.addEventListener('click', foo('myarg'), true);
. Thefoo('myarg')
will return another function withargumentToPass
set tomyarg
. Just remember in real code to keep hold of a reference to the fn :-) -
Arh Hokagi over 2 years@joseluisq can you please explain what bind(this) means? it works but i dont know why
-
Mike 'Pomax' Kamermans over 2 yearsNote that as of late 2020 we don't need removeEventListener to remove an event listener, we can use an abort signal now, which means we don't need to construct a reference to the original function at all, instead we can use an AbortController
-
Jinu Joseph Daniel over 2 yearsGood information. Good to see answers coming even 9 years after the question date.
-
Mike 'Pomax' Kamermans over 2 yearsJS is always changing, some topics deserve follow-ups: what was the only solution and the right answer as little as a few years ago can be completely obsolete today, which is certainly the case here (especially with IE only having months left to live for the entire product line. Finally =)
-
Shivam over 2 yearsThis saved my life, I thought it's const so it wouldn't be redeclared on re render but ...
-
paddotk about 2 years@ArhHokagi
.bind(this)
puts the function on a higher-level scope, makingthis
becoming the scope of where the function resides. If you use ES6 syntax, this won't be necessary ever.