无法删除所有事件侦听器

时间:2018-01-20 22:54:42

标签: javascript event-listener

我正试图从某个网站删除事件监听器,但我没有成功。

这是来自网站的事件听众:
enter image description here

有一个javascript脚本可以使用以下命令创建这些事件:

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

我试图将其删除:

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

我也尝试过:

(getEventListeners(document)).contextmenu = null

但它没有用,我想因为我使用的是一个不同的新功能。

有没有办法清除所有事件?

引用


Can't remove event listener

4 个答案:

答案 0 :(得分:3)

您需要指定绑定到removeEventListener

的函数

您可以通过创建一个函数并将引用传递给addEventListenerremoveEventListener来完成此操作。



// 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)




这是一个完整的示例,它将所有事件缓存到元素,允许您删除特定事件,所有事件类型的所有事件。

它还有一个MutationObserver观察DOM的变化,如果一个元素被删除,那么附加到它的事件。



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>
&#13;
&#13;
&#13;

答案 1 :(得分:1)

您可以尝试克隆已添加所有侦听器的元素,并将其添加回其父级。使用cloning,您将丢失附加到该元素的所有侦听器。试试这个,

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

element.parentNode.replaceChild(clone, element);

但是,这不会对全局事件监听器起作用,或者只是直接在文档而不是元素上设置,因为文档是层次结构的根(不能有parentNode)

答案 2 :(得分:0)

要删除未知的事件侦听器,您可以clone该元素,然后将原始内容移动到克隆的内容中,然后用克隆替换原始内容。

如果您不关心所包含元素的事件侦听器,您还可以使用.clone(true)(或false,或不记得)深度克隆原始内容。然后你不必移动内容。

答案 3 :(得分:0)

document.getElementsById("id").removeAllListeners()