javascript tutorial - [Solved-5 Solutions] How to find event listeners on a DOM node when debugging or from the javascript code ? - javascript - java script - javascript array



Problem:

We have a page where some event listeners are attached to input boxes and select boxes. Is there a way to find out which event listeners are observing a particular DOM node and for what event? Events are attached using:

  • Prototype's Event.observe;
  • DOM's addEventListener;
  • As element attribute element.onclick.

Solution 1:

If we just need to inspect what's happening on a page, we might try the Visual Eventbookmarklet. Update: Visual Event 2available;

Solution 2:

It depends on how the events are attached. For illustration presume we have the following click handler:

var handler = function() { alert('clicked!') };
click below button to copy the code. By JavaScript tutorial team

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
alert(element.onclick); // alerts "function() { alert('clicked!') }"
click below button to copy the code. By JavaScript tutorial team

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
click below button to copy the code. By JavaScript tutorial team

Method C): jQuery

$(element).click(handler);
click below button to copy the code. By JavaScript tutorial team

1.3.x

	// inspect
	var clickEvents = $(element).data("events").click;
	jQuery.each(clickEvents, function(key, value) {
	    alert(value) // alerts "function() { alert('clicked!') }"
})
click below button to copy the code. By JavaScript tutorial team

1.4.x (stores the handler inside an object)

	// inspect
	var clickEvents = $(element).data("events").click;
	jQuery.each(clickEvents, function(key, handlerObj) {
	    alert(handlerObj.handler) // alerts "function() { alert('clicked!') }"
	    // also available: handlerObj.type, handlerObj.namespace
})
click below button to copy the code. By JavaScript tutorial team

(See jQuery.fn.data and jQuery.data) Method D): Prototype (messy)

$(element).observe('click', handler);
click below button to copy the code. By JavaScript tutorial team

1.5.x

	// inspect
	Event.observers.each(function(item) {
	    if(item[0] == element) {
	        alert(item[2]) // alerts "function() { alert('clicked!') }"
	    }
})
click below button to copy the code. By JavaScript tutorial team

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){
	    alert(wrapper.handler) // alerts "function() { alert('clicked!') }"
})
click below button to copy the code. By JavaScript tutorial team

1.6.1 (little better)

	// inspect
	var clickEvents = element.getStorage().get('prototype_event_registry').get('click');
	clickEvents.each(function(wrapper){
	    alert(wrapper.handler) // alerts "function() { alert('clicked!') }"
})

click below button to copy the code. By JavaScript tutorial team

Solution 3:

Chrome, Firefox, Vivaldwe and Safarwe support getEventListeners(domElement) in their Developer Tools console. For majority of the debugging purposes, this could be used.

Solution 4:

It is possible to list all event listeners in JavaScript: It's not that hard; we just have to hack the prototype's method of the HTML elements (before adding the listeners).

function reportIn(e){
    var a = this.lastListenerInfo[this.lastListenerInfo.length-1];
    console.log(a)
}


HTMLAnchorElement.prototype.realAddEventListener = HTMLAnchorElement.prototype.addEventListener;

HTMLAnchorElement.prototype.addEventListener = function(a,b,c){
    this.realAddEventListener(a,reportIn,c); 
    this.realAddEventListener(a,b,c); 
    if(!this.lastListenerInfo){  this.lastListenerInfo = new Array()};
    this.lastListenerInfo.push({a : a, b : b , c : c});
};
click below button to copy the code. By JavaScript tutorial team

Now every anchor element (a) will have a lastListenerInfo property wich contains all of its listeners. And it even works for removing listeners with anonymous functions.

Solution 5:

When debugging, if we just want to see the events, we recommend either...

  • Visual Event
  • The Elements section of Chrome's Developer Tools: select an element and look for "Event Listeners" on the bottom right (similar in Firefox)

If we want to use the events in our code, and we are using jQuery before version 1.8, we can use:

$(selector).data("events")
click below button to copy the code. By JavaScript tutorial team

To get the events. As of version 1.8, using .data("events") is discontinued (see this bug ticket). We can use:

$._data(element, "events")
click below button to copy the code. By JavaScript tutorial team

Another example: Write all click events on a certain link to the console:

var $myLink = $('a.myClass');
console.log($._data($myLink[0], "events").click);
click below button to copy the code. By JavaScript tutorial team

Unfortunately, using $._data this is not recommended except for debugging since it is an internal jQuery structure, and could change in future releases. Unfortunately we know of no other easy means of accessing the events.


Related Searches to javascript tutorial - How to find event listeners on a DOM node when debugging or from the javascript code ?