Javascript removeEventListener not working

117,045

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);
Share:
117,045
Jinu Joseph Daniel
Author by

Jinu Joseph Daniel

Interested in programming and development

Updated on July 08, 2022

Comments

  • Jinu Joseph Daniel
    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
    Jinu Joseph Daniel about 12 years
    but how can i pass arguments(here event ) to that function..That's why i used anonymous function
  • ThiefMaster
    ThiefMaster about 12 years
    It is passed by the browser. It doesn't matter if you define the function separately or not.
  • NiRUS
    NiRUS about 7 years
    +1 True. bind(this) will change the signature. So always assign the function to a var after binding this to using function bind API so that same var can be used in removeListener. You will see this problem more evident in typescript
  • IC_
    IC_ about 7 years
    That won't allow you to pass function parameters f.e. foo(1)
  • David Edwards
    David Edwards over 6 years
    I'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
    David Edwards over 6 years
    Addendum 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
    VectorVortec over 6 years
    You should ask a new question. This area answers the OP's question.
  • David Edwards
    David Edwards over 6 years
    WARNING: 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
    Mave over 5 years
    I 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
    joseluisq about 5 years
    If someone use classes try something like this.onClick = this.onClick.bind(this) before any listener, then btn.addEventListener('click', this.onClick), finally btn.removeEventListener('click', this.onClick)
  • raven-king
    raven-king over 2 years
    @Herrgott To pass arguments to the handler function you can use currying: foo = (argumentToPass) => (event) => { doSomething(); }, then xyz.addEventListener('click', foo('myarg'), true);. The foo('myarg') will return another function with argumentToPass set to myarg. Just remember in real code to keep hold of a reference to the fn :-)
  • Arh Hokagi
    Arh Hokagi over 2 years
    @joseluisq can you please explain what bind(this) means? it works but i dont know why
  • Mike 'Pomax' Kamermans
    Mike 'Pomax' Kamermans over 2 years
    Note 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
    Jinu Joseph Daniel over 2 years
    Good information. Good to see answers coming even 9 years after the question date.
  • Mike 'Pomax' Kamermans
    Mike 'Pomax' Kamermans over 2 years
    JS 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
    Shivam over 2 years
    This saved my life, I thought it's const so it wouldn't be redeclared on re render but ...
  • paddotk
    paddotk about 2 years
    @ArhHokagi .bind(this) puts the function on a higher-level scope, making this becoming the scope of where the function resides. If you use ES6 syntax, this won't be necessary ever.