Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

183
Views
remove event listener without knowing what the call back function is

Lets say we add a even listener to a button like this

function handler(){
 alert(0)
}
btn.addEventListener("click", handler)

now if we want to remove event listener we can simply do: btn.removeEventListener("click", handler)

but what if we don't have access to the handler function. for example, some third-party library is attaching an event listener to an element and I want to remove it. how can we do so?

about 4 years ago · Juan Pablo Isaza
3 answers
Answer question

0

As written in comments, you can't remove an event listener without having the callback reference unless you re-create/clone that element, which can be problematic sometimes and also does not seem to be good practice or particularly performant (Spoiler Alert - None of the possible solutions can be completely considered good practice because your situation isn't ideal from the beginning).

As an alternative, you can try something like this:

element.addEventListener('click', (e) => {
  e.stopImmediatePropagation();
  e.stopPropagation();
}, true);

Odds are that your third-party library will be listening to the event on the bubbling phase. If so, doing this on the capture phase (see addEventListener third argument) will prevent your third-party listeners from firing.

Please note that this will break event propagation at the capture phase. This means that any listener set on the bubbling phase for that event, triggered on that element or any of its children will not fire. Also the remaining listeners on the capture phase will not fire either.

Leveraging Event's Nature

If you add the above event listener before your third-party library adds its own event listeners, you can be "more sure" that yours will be fired first.

Please consider that capture phase listeners will ALWAYS be fired before bubbling phase listeners and that element's DOM order will ALWAYS be respected.

What is a bit unpredictable is the execution order for multiple listeners for the same event on the same phase and on the same target element. See Event Order.

With that being said, if you add the above listener to the PARENT of your interested element, you can be 99% sure that your third-party library listener will not be executed and this comes with almost zero performance impact. (The remaining 1% is for the case in which the library somehow adds an event listener on the capture phase and on a previous ancestor than yours, that could also be the window object).

If you want to still fire listeners for the parent element you can filter out cases using event.target property.

Something like:

parent.addEventListener('click', (e) => {
  if (element.contains(e.target)) {
    e.stopPropagation();
  }
}, true);

Final Note

I took the time to write all this more as a didactic example about DOM events than as an actual working solution. This is because any possible solution that I can think about right now will have some kind of drawback, issue or limitation (performance, debugging, unpredictability, etc.)

about 4 years ago · Juan Pablo Isaza Report

0

A simpler way is to clone node and its child elements to remove all the listeners.

function recreateNode(el, withChildren) {
  if (withChildren) {
    el.parentNode.replaceChild(el.cloneNode(true), el);
  }
  else {
    var newEl = el.cloneNode(false);
    while (el.hasChildNodes()) newEl.appendChild(el.firstChild);
    el.parentNode.replaceChild(newEl, el);
  }
}

Here withChildren: true will replace all nested elements as well. With your question, You don't need to find out the reference function.

about 4 years ago · Juan Pablo Isaza Report

0

This is what I tried(It didnt work tho)

function removeEListener(element, event){
    let listeners = getEventListeners(element)[event]
    try{
        listeners.forEach(listener => {
            listener.remove()
            element.removeEventListener(event, listener.listener, listener.useCapture)
        })
    }catch(e){
        console.log(e)
    }
}
removeEListener(document.querySelector(".btn"), 'click')
about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!