Wednesday, March 23, 2011

How to find event listeners on a DOM node?

I 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 1) prototype's Event.observe 2) DOM's addEventListener 3) as element attribute element.onclick

From stackoverflow
  • 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
    alert(element.onclick); // alerts "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) {
          alert(value) // alerts "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) {
          alert(handlerObj.handler) // alerts "function() { alert('clicked!') }"
          // also available: handlerObj.type, handlerObj.namespace
      })
      

    (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) {
              alert(item[2]) // alerts "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){
          alert(wrapper.handler) // alerts "function() { alert('clicked!') }"
      })
      
    • 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!') }"
      })
      
    Keith Bentrup : Thx for updating this. It's unfortunate that you have to iterate thru each type of handler.
  • If you have Firebug, you can use console.dir(object or array) to print a nice tree in the console log of any javascript scalar, array, or object. Try: console.dir(clickEvents); or console.dir(window);

  • If you just need to inspect what's happening on a page, you might try the Visual Event bookmarklet.

    Brian Wigginton : This tool is awesome, thanks for posting.

0 comments:

Post a Comment