How to find event listeners on a DOM node when debugging or from the JavaScript code?
If you just need to inspect what's happening on a page, you might try the Visual Event bookmarklet.
Update: Visual Event 2 available.
Chrome, Firefox, Vivaldi and Safari support getEventListeners(domElement)
in their Developer Tools console.
For majority of the debugging purposes, this could be used.
Below is a very good reference to use it: https://developers.google.com/web/tools/chrome-devtools/console/utilities#geteventlisteners
It depends on how the events are attached. For illustration presume we have the following click handler:
var handler = function() { alert('clicked!') };
We're going to attach it to our element using different methods, some which allow inspection and some that don't.
Method A) single event handler
element.onclick = handler;
// inspect
console.log(element.onclick); // "function() { alert('clicked!') }"
Method B) multiple event handlers
if(element.addEventListener) { // DOM standard
element.addEventListener('click', handler, false)
} else if(element.attachEvent) { // IE
element.attachEvent('onclick', handler)
}
// cannot inspect element to find handlers
Method C): jQuery
$(element).click(handler);
1.3.x
// inspect var clickEvents = $(element).data("events").click; jQuery.each(clickEvents, function(key, value) { console.log(value) // "function() { alert('clicked!') }" })
1.4.x (stores the handler inside an object)
// inspect var clickEvents = $(element).data("events").click; jQuery.each(clickEvents, function(key, handlerObj) { console.log(handlerObj.handler) // "function() { alert('clicked!') }" // also available: handlerObj.type, handlerObj.namespace })
1.7+ (very nice)
Made using knowledge from this comment.
events = $._data(this, 'events'); for (type in events) { events[type].forEach(function (event) { console.log(event['handler']); }); }
(See jQuery.fn.data
and jQuery.data
)
Method D): Prototype (messy)
$(element).observe('click', handler);
1.5.x
// inspect Event.observers.each(function(item) { if(item[0] == element) { console.log(item[2]) // "function() { alert('clicked!') }" } })
1.6 to 1.6.0.3, inclusive (got very difficult here)
// inspect. "_eventId" is for < 1.6.0.3 while // "_prototypeEventID" was introduced in 1.6.0.3 var clickEvents = Event.cache[element._eventId || (element._prototypeEventID || [])[0]].click; clickEvents.each(function(wrapper){ console.log(wrapper.handler) // "function() { alert('clicked!') }" })
1.6.1 (little better)
// inspect var clickEvents = element.getStorage().get('prototype_event_registry').get('click'); clickEvents.each(function(wrapper){ console.log(wrapper.handler) // "function() { alert('clicked!') }" })
When clicking the resulting output in the console (which shows the text of the function), the console will navigate directly to the line of the function's declaration in the relevant JS file.