Last Updated: December 17, 2018
·
115.9K
· jimmyhchan

Getting a list of your eventListeners so you can trigger it programmatically

Ever wonder why it is so hard to trigger keydown or click events programmatically in pure JS? Should be easy right? Just ... trigger it right?

elem.click();   /* elem has no method click :( */

uhh... unlike elem.focus or elem.blur which are functions and are callable, there is no elem.click or elem.keydown methods.

That makes sense since.. sort of... let's think.

Instead of triggering the event, what we want is for all the eventListeners to fire. Let's get the list of eventListeners and fire each one! That should work!... right?

var myElement = document.getElementById('foo');
var myKeyDownEvents = getEventListeners(myElement, 'keydown');
myKeyDownEvents.forEach( function(keyDownEvent) {
     keyDownEvent.call();
});

/* what would getEventListeners look like? */
var getEventListeners = function(elem, type) {
  if (elem.eventListenerList) {
     return elem.eventListenerList;
  }else {
     /* derp?!*/
  }
}

Problem is, it turns out getting the list of event listeners on an element is currently impossible.. unless --like every good StackOverflow JS question-- you just use jQuery!!.

What? Seriously! I can't get the eventListenerList unless I use jQuery! Why?
jQuery, YUI, Moo etc. keeps a copy of the eventListeners when you add them to elements so that you have access to a list. So for those libraries:

var getEventListeners = function(elem, type) {
  return getFromGlobalCache(elem, type);
}

Ewww... any work arounds?
If you just can put everything into a single method and can avoid using addEventListener (not recommended in general) then you can assign the single method directly to the element's on* property. For example,element.onclick = clickHandler or element.onkeydown = keyDownHandler.

what if i just want to see my eventListeners
That's easier! If you just need to inspect, Chrome/Webkit inspector allows you to see the events.

The Future
According to DOM 3 Events, when you used addEventListener there should be an event listener list (EventListenerList DOM 3 Events), but it has yet to be implemented by any browser (Sept, 2012). Until then there is no easy getEventListener method. If you want to programmatically triggering events, keep a copy of a list globally or use a library.

Further reading
http://stackoverflow.com/a/447106/1361988
https://github.com/jquery/jquery/blob/master/src/event.js
http://stackoverflow.com/questions/7810534/have-any-browsers-implemented-the-dom3-eventlistenerlist
http://www.w3.org/TR/2001/WD-DOM-Level-3-Events-20010823/events.html#Events-EventListenerList

3 Responses
Add your response

Nice article, but to trigger registered events programatically on any DOM element, you can use the EventTarget.dispatchEvent method, like for example:
btn=document.getElementById('buttonx');
btn.dispatchEvent(new MouseEvent('click')); // this will make any click event listener on the button to be invoked
you can also use (new Event('click') simply)
But what you have said in this article still usefull if you want to see the list of event listeners. may be for debugging purpose.

over 1 year ago ·

@nafaabout Thanks! I knew about dispatchEvent but didn't know you could trigger built-in methods with it. Older IE versions seem to support fireEvent but I'm not sure if they support something like new MouseEvent('click').

Re-reading this today and with your comment, I think "The Future" should really be using the native customEvent, using dispatchEvent and dropping support for IE <8.

over 1 year ago ·

Chrome now has just such a function, and it's actually called getEventListeners(). Obviously you can't use it in a real script since it only works in Chrome, but it's useful for debugging. Found out about it here: http://stackoverflow.com/a/17466308/560114

over 1 year ago ·