2

I am trying to remove event listeners from some website but I don't succeed to do it.

This is the event listeners from the website:
enter image description here

There is a javascript script that creates these events with:

document.addEventListener('contextmenu', function (ev) {
        ev.preventDefault();
    }
)

I tried to remove it with:

document.removeEventListener('contextmenu', function (ev) {
                ev.preventDefault();
            }) 

I also tried with:

(getEventListeners(document)).contextmenu = null

But it didn't work, I think because I am using a new function which is not the same one.

Is there a way just to clear all the events ?

Referenced:
Can't remove event listener

E235
  • 11,560
  • 24
  • 91
  • 141

3 Answers3

5

You need to specify the function that was bound to removeEventListener

You can do this by creating a function and passing a reference to both addEventListener and removeEventListener.

// create a function
function onRightClick(ev) {
  ev.preventDefault();
  console.log('onRightClick')
}

// pass the function to both add and remove
document.addEventListener('contextmenu', onRightClick)
document.removeEventListener('contextmenu', onRightClick)

Here is a full example that will cache all the events to the element allowing you to remove specific events, all events for a type of all events.

It's also got a MutationObserver watching the DOM for changes, if an element get's removed so will the events attached to it.

const Events = (() => {
  
  const cache = new Map
  
  const observer = new MutationObserver(function(mutations) {
    for (let mutation of mutations) {
      if (mutation.type === 'childList') {
        if (mutation.removedNodes.length) {
          console.log('element removed from the dom, removing all events for the element')
          mutation.removedNodes.forEach(x => Events.remove(x))
        }
      }
    }
  })
  
  // watch the dom for the element being deleted
  observer.observe(document.body, { childList: true })
  
  return {
  
    add(el, type, fn, capture = false) {
      let cached = cache.get(el)
      if (!cached) {
        cached = {}
        cache.set(el, cached)
      }
      if (!cached[type]) {
        cached[type] = new Set
      }
      cached[type].add(fn)
      el.addEventListener(type, fn, capture)
    },
    
    remove(el, type, fn) {
      const cached = cache.get(el)
      if (!cached) {
        return false
      }
      // remove all events for an event type
      if (type && !fn) {
        cached[type].forEach(fn => {
          el.removeEventListener(type, fn)
        })
        cached[type] = new Set
      }
      // remove a specific event
      else if (type && fn) {
        el.removeEventListener(type, fn)
        // remove the event from the cache
        cached[type].delete(fn)
      }
      // remove all events for the element
      else {
        for (key in cached) {
          cached[key].forEach(fn => {
            el.removeEventListener(key, fn)
          })
        }
        cache.delete(el)
      }
    },
    
    show(el, type) {
      const cached = cache.get(el)
      if (!cached) {
        return false
      }
      if (type) {
        return cached[type]
      }
      return cached
    }
  }
})()

function onRightClick() {}

Events.add(document, 'contextmenu', onRightClick)
Events.remove(document, 'contextmenu', onRightClick) // remove a specific event callback
Events.remove(document, 'contextmenu') // remove specific event types from an element
Events.remove(document) // remove all events from an element


const testElement = document.querySelector('#test_element')

Events.add(testElement, 'click', function deleteSelf(e) {
  this.parentNode.removeChild(this)
})
<div id="test_element">
  when you <strong>click me</strong> I will be deleted from the DOM which will fire the MutationObserver to remove all my events
</div>
synthet1c
  • 6,152
  • 2
  • 24
  • 39
2

You can try cloning the element to which you've added all the listeners and add it back to its parent. With cloning, you lose all the listeners attached to the element. Try this,

var element = document.getElementById('myElement'),
    clone = el.cloneNode(true);

element.parentNode.replaceChild(clone, element);

However, this won't work on global event listeners, or simply, those set directly on document instead of an element as the document is the root of hierarchy (can't have parentNode)

Nilesh Singh
  • 1,750
  • 1
  • 18
  • 30
0

To get rid of unknown event listeners you can clone the element and then move the original's content into the cloned one and then replace the original one with the clone.

If you don't care about the contained elements' event listeners, you can also deep clone the original with .clone(true) (or false, can't remember). Then you don't have to move the contents over.

DanMan
  • 11,323
  • 4
  • 40
  • 61
  • A fellow SOer seems to think that's not a good solution https://stackoverflow.com/questions/9251837/how-to-remove-all-listeners-in-an-element#comment11660996_9251864 – Neithan Max Dec 06 '18 at 14:08