How to Remove All Listeners in an Element

How to remove all listeners in an element?

I think that the fastest way to do this is to just clone the node, which will remove all event listeners:

var old_element = document.getElementById("btn");
var new_element = old_element.cloneNode(true);
old_element.parentNode.replaceChild(new_element, old_element);

Just be careful, as this will also clear event listeners on all child elements of the node in question, so if you want to preserve that you'll have to resort to explicitly removing listeners one at a time.

Remove All Event Listeners of Specific Type

That is not possible without intercepting addEventListener calls and keep track of the listeners or use a library that allows such features unfortunately. It would have been if the listeners collection was accessible but the feature wasn't implemented.

The closest thing you can do is to remove all listeners by cloning the element, which will not clone the listeners collection.

Note: This will also remove listeners on element's children.

var el = document.getElementById('el-id'),
elClone = el.cloneNode(true);

el.parentNode.replaceChild(elClone, el);

Javascript/DOM: How to remove all event listeners of a DOM object?

I am not sure what you mean with remove all events. Remove all handlers for a specific type of event or all event handlers for one type?

Remove all event handlers

If you want to remove all event handlers (of any type), you could clone the element and replace it with its clone:

var clone = element.cloneNode(true);

Note: This will preserve attributes and children, but it will not preserve any changes to DOM properties.



Remove "anonymous" event handlers of specific type

The other way is to use removeEventListener() but I guess you already tried this and it didn't work. Here is the catch:

Calling addEventListener to an anonymous function creates a new listener each time. Calling removeEventListener to an anonymous function has no effect. An anonymous function creates a unique object each time it is called, it is not a reference to an existing object though it may call one. When adding an event listener in this manner be sure it is added only once, it is permanent (cannot be removed) until the object it was added to, is destroyed.

You are essentially passing an anonymous function to addEventListener as eventReturner returns a function.

You have two possibilities to solve this:

  1. Don't use a function that returns a function. Use the function directly:

     function handler() {
    dosomething();
    }

    div.addEventListener('click',handler,false);
  2. Create a wrapper for addEventListener that stores a reference to the returned function and create some weird removeAllEvents function:

     var _eventHandlers = {}; // somewhere global

    const addListener = (node, event, handler, capture = false) => {
    if (!(event in _eventHandlers)) {
    _eventHandlers[event] = []
    }
    // here we track the events and their nodes (note that we cannot
    // use node as Object keys, as they'd get coerced into a string
    _eventHandlers[event].push({ node: node, handler: handler, capture: capture })
    node.addEventListener(event, handler, capture)
    }

    const removeAllListeners = (targetNode, event) => {
    // remove listeners from the matching nodes
    _eventHandlers[event]
    .filter(({ node }) => node === targetNode)
    .forEach(({ node, handler, capture }) => node.removeEventListener(event, handler, capture))

    // update _eventHandlers global
    _eventHandlers[event] = _eventHandlers[event].filter(
    ({ node }) => node !== targetNode,
    )
    }

And then you could use it with:

    addListener(div, 'click', eventReturner(), false)
// and later
removeAllListeners(div, 'click')

DEMO

Note: If your code runs for a long time and you are creating and removing a lot of elements, you would have to make sure to remove the elements contained in _eventHandlers when you destroy them.

Removing all eventListeners by class

The 2nd argument to removeEventListener() must be a reference to the function that is assigned to the event as listener but you are passing a new, literal arrow function.

In the example, the 2nd occurrence of () => {selectSelf(name)} is a new arrow function declared literally. The one that was already added as an event handler is a different function so you cannot expect it to be removed.

To make it work, save a reference to each handler function that you can later pass to removeEventListener():

let names = document.querySelectorAll('.playerName');
const handlers = [];

names.forEach((name) => {
// Use a unique identifier for each function reference
handlers[name.id] = () => selectSelf(name);

name.addEventListener('click', handlers[name.id]);
});

function dropEvents() {
let drops = document.querySelectorAll('.playerName');
drops.forEach((drop) => {
drop.removeEventListener('click', handlers[drop.id]);
});
}

Removing event listeners added by class

Finally, I have figured out how to resolve this issue. The way to remove the listener is to go to parent div component & call removeAllListeners() method on the element. The element can be accessed in the afterRenderHandler function using this.el & then calling this.el.parent().removeAllListeners() so that it removes the un-required listeners interfering with the user experience. You could call the parent method in a chained fashion if the listener identified is a nth level parent (call the method n times).

Ex: this.el.parent().parent().removeAllListeners()

You could also try to access the element directly if you have the ID by calling: var el = Ext.get('mainMenu'); & then calling el.removeAllListeners();

Similar approach can be applied to any other JS frameworks by getting a handle to the element having an issue with the listeners.



Related Topics



Leave a reply



Submit