3

Is there any way to get the list of all event listeners of an element on the HTML page using JavaScript on that page.

Note: I know we can see them with Chrome dev tools event listeners but I want to log/access see list using the JavaScript of the page.

Also, I know we can get them through jQuery but for that, we also have to apply the events using jQuery, but I want something that would be generic so I could also access the event listeners applied to other elements such as web components or react components.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Yasir 768
  • 31
  • 1
  • 2

2 Answers2

6

If you really had to, a general way to do this would be to patch EventTarget.prototype.addEventListener:

const listeners = [];
const orig = EventTarget.prototype.addEventListener;
EventTarget.prototype.addEventListener = function(...args) {
  if (this instanceof HTMLElement) {
    listeners.push({
      type: args[0],
      fn: args[1],
      target: this,
    });
  }
  return orig.apply(this, args);
};

document.body.addEventListener('click', () => console.log('body clicked'));
console.log(listeners[0].fn);
click this body

To find listeners attached to an element, iterate through the listeners array and look for targets which match the element you're looking for.

To be complete, also patch removeEventListener so that items can be removed from the array when removed.

If you need to watch for listeners attached via on, then you'll have to do something similar to the above to patch the HTMLElement.prototype.onclick getter/setter, and for each listener you want to be able to detect.

That said, although you said you want a generic solution, rather than patching built-in prototypes, it'd be better to add the listeners through jQuery or through your own function.

CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • But then OP should also implement `.removeEventListener()` (when needed) to get rid of the stored handler references. And handlers defined with the `on` attributes will be missing. – Andreas Sep 16 '20 at 06:18
  • 1
    Firstly, Thank you so much for your answer, I really appreciate it. But actually I needed a generic way to do it as I'm working with web components and in that we're adding the events according to their own methods and we're not actually wanting to patch them, but looking for a way to fetch them in the script as they can already be seen on the chrome dev tools. – Yasir 768 Sep 16 '20 at 11:22
0

What I did when I had a similar problem is add a data attribute when the listener was set, so I could identify it later.

At the end of the function that adds the listener:

elm.setAttribute('data-has_mask', true);

At the beginning of that same function:

if("true" == elm.getAttribute('data-has_mask')) {
    return;
}

Maybe not exactly what the OP is looking for, but I was having a lot of trouble with this, and this is an obvious solution for a particular use case, and I guess it might help someone out.

iateadonut
  • 1,951
  • 21
  • 32