Remove All Event Listeners of Specific Type

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.

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.

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]);
});
}

How to remove all event listeners from a display object?

jeceuyper is right ...

a side not though: DisplayObject extends EventDispatcher, which already does implement IEventDispatcher ... so to be more precise: you need to override addEventListener and removeEventListener to keep track of the listeners ...

a few technical details: i suggest you use Dictionary to store the handler functions ... a bit slower for insertion, but much faster for removal ... also, Dictionary supports weak references, which is quite important in the case of event handling ... also keep in mind, that useCapture allows to add the same handler twice ...

good luck then ... ;)

Can't remove keydown event listener programtically

Instead of removing it, you could add an event listener to all textarea elements to prevent the default behavior and also stop propagation of the event to parent elements.

document.querySelectorAll("textarea").forEach(e => {
e.addEventListener("keydown", ev => {
ev.preventDefault();
ev.stopPropagation();
})
})

Note that this is solution to your scenario, but it does not answer your initial question of how to remove an event listener. If there were other keydown event listeners added to the textarea elements, those would not be removed. In order to actually remove the event listeners, you can look at these other questions:

  • Remove All Event Listeners of Specific Type
  • Javascript/DOM: How to remove all event listeners of a DOM object?


Related Topics



Leave a reply



Submit