20

There are 24 div-objects waiting/listening for a mouse-click. After click on one div-object, I want to remove the EventListener from all 24 div-objects.

for (var i=1;i<=24;i++){
    document.getElementById('div'+i).addEventListener('click',function(event){
        for (var z=1;z<=24;z++){
            document.getElementById('div'+z).removeEventListener()//Problem lies here
        }

        //Some other code to be run after mouseclick

        },false);

}

The problem is that the removeEventListener is nested in addEventListener and I need to define type, listener, caption as attributes to the removeEventListener method. And I think it is impossible to define the listener because of nesting.

I also tried to define a function name, but it didn't worked:

for (var i=1;i<=24;i++){
    document.getElementById('div'+i).addEventListener('click',function helpme(event){
        for (var z=1;z<=24;z++){
            document.getElementById('div'+z).removeEventListener('click',helpme,false);
        }

        //Some other code to be run after mouseclick

        },false);

}

4 Answers 4

55

You can tell the event listener to simply fire just once:

document.addEventListener("click", (e) => {
            // function which to run on event
}, { once: true });

The documentation says:

once: A boolean value indicating that the listener should be invoked at most once after being added. If true, the listener would be automatically removed when invoked.

Sign up to request clarification or add additional context in comments.

2 Comments

As of 2021, this is the correct answer.
Is there a way to remove the listener not after firing, but when the if condition is met? (like addEventListener('action', function () { if (sth) {code; removeListener});
16

It should work with a named function. If your second approach does not work properly, try storing the initial listener into a variable, like this:

var handler = function(event) {
    for(...) {
        removeEventListener('click', handler, false);
    }
};

addEventListener('click', handler, false);

Ps. if you care about speed, you may wish to consider using just one event handler. You can put the handler into the parent element of the divs, and then delegate the event from there. With 24 handlers your current approach probably doesn't have a very big performance hit, but this is something you should keep in mind if it ever feels slow.

4 Comments

Hi Jani! It worked! I wanna thank you so much! I tried to figur out all day long without any success
Old topic, but for some reason this wasn't working for me. An alternative that worked for me (to stop the event listener) was to set the event listener to an empty function.
Hi Jani, how is it that you can call handler in the removeEventListener when defining handler? It seems circular to me, but I'm misunderstanding something obviously!
The third parameter (useCapture) is optional and false by default, so it does not require specifying.
5

For those who needs to remove after a certain condition (or even inside a loop too), one alternative is using AbortController and AbortSignal:

const abortController = new AbortController();

let handler = function(event) {
    if(...) {
        abortController.abort();
    }
};

addEventListener('click', handler, {signal: abortController.signal});

Comments

-3

The same answer:

element.addEventListener("click", (e) => {
  // function which to run on event 
}, { once: true });

You can read more here: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener

1 Comment

Don't repeat other people's answers

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.