Tuesday, May 29, 2012

How to debug Javascript/jQuery event bindings with FireBug (or similar tool)


I need to debug a web application that uses jQuery to do some fairly complex and messy DOM manipulation. At one point, some of the events that were bound to particular elements, are not fired and simply stop working.



If I had a capability to edit the application source, I would drill down and add a bunch of Firebug console.log() statements and comment/uncomment pieces of code to try to pinpoint the problem. But let's assume I cannot edit the application code and need to work entirely in Firefox using Firebug or similar tools.



Firebug is very good at letting me navigate and manipulate the DOM. So far, though, I have not been able to figure out how to do event debugging with Firebug. Specifically, I just want to see a list of event handlers bound to a particular element at a given time (using Firebug Javascript breakpoints to trace the changes). But either Firebug does not have the capability to see bound events, or I'm too dumb to find it. :-)



Any recommendations/ideas? Ideally, I would just like to see and edit events bound to elements, similarly to how I can edit DOM today.


Source: Tips4all

13 comments:

  1. See How to find event listeners on a DOM node.

    In a nutshell, assuming at some point an event handler is attached to your element (eg): $('#foo').click(function() { console.log('clicked!') });

    You inspect it like so:


    jQuery 1.3.x

    var clickEvents = $('#foo').data("events").click;
    jQuery.each(clickEvents, function(key, value) {
    console.log(value) // prints "function() { console.log('clicked!') }"
    })

    jQuery 1.4.x

    var clickEvents = $('#foo').data("events").click;
    jQuery.each(clickEvents, function(key, handlerObj) {
    console.log(handlerObj.handler) // prints "function() { console.log('clicked!') }"
    })



    See jQuery.fn.data (where jQuery stores your handler internally).

    ReplyDelete
  2. There's a nice bookmarklet called Visual Event that can show you all the events attached to an element. It has color-coded icons for different types of events (mouse, keyboard, etc.).

    ReplyDelete
  3. The Eventbug extension has been released yesterday, see:
    http://www.softwareishard.com/blog/firebug/eventbug-alpha-released/

    Honza

    ReplyDelete
  4. You could use FireQuery. It shows any events attached to DOM elements in the Firebug's HTML tab. It also shows any data attached to the elements through $.data.

    ReplyDelete
  5. Here's a plugin which can list all event handlers for any given element/event:

    $.fn.listHandlers = function(events, outputFunction) {
    return this.each(function(i){
    var elem = this,
    dEvents = $(this).data('events');
    if (!dEvents) {return;}
    $.each(dEvents, function(name, handler){
    if((new RegExp('^(' + (events === '*' ? '.+' : events.replace(',','|').replace(/^on/i,'')) + ')$' ,'i')).test(name)) {
    $.each(handler, function(i,handler){
    outputFunction(elem, '\n' + i + ': [' + name + '] : ' + handler );
    });
    }
    });
    });
    };


    Use it like this:

    // List all onclick handlers of all anchor elements:
    $('a').listHandlers('onclick', console.info);

    // List all handlers for all events of all elements:
    $('*').listHandlers('*', console.info);

    // Write a custom output function:
    $('#whatever').listHandlers('click',function(element,data){
    $('body').prepend('<br />' + element.nodeName + ': <br /><pre>' + data + '<\/pre>');
    });


    Src: (my blog) -> http://james.padolsey.com/javascript/debug-jquery-events-with-listhandlers/

    ReplyDelete
  6. The WebKit Developer Console (found in Chrome, Safari, etc.) lets you view attached events for elements.

    ReplyDelete
  7. jquery stores events in the following:
    $("a#somefoo").data("events")

    doing a console.log($("a#somefoo").data("events")) should list the events attached to that element.

    ReplyDelete
  8. As a colleague suggested, console.log > alert:

    var clickEvents = $('#foo').data("events").click;
    jQuery.each(clickEvents, function(key, value) {
    console.log(value);
    })

    ReplyDelete
  9. There are a few very good tools for debugging jquery running as Firefox plugins. I wrote an article about this on my blog at http://johnayling.com/programming-tips/debugging-jquery-code.

    If you look halfway down the article I show you how to use firefinder to debug jquery events.

    ReplyDelete
  10. According to this thread, there is no way in Firebug to view what events are attached to listeners on a DOM element.

    It looks like the best you can do is either what tj111 suggests, or you could right-click the element in the HTML viewer, and click "Log Events" so you can see which events are firing for a particular DOM element. I suppose one could do that to see what events could be firing off particular functions.

    ReplyDelete
  11. Looks like FireBug crew is working on an EventBug extension. It will add another panel to FireBug - Events.

    "The events panel will list all of the event handlers on the page grouped by event type. For each event type you can open up to see the elements the listeners are bound to and summary of the function source." EventBug Rising

    Although they cannot say right now when it will be released.

    ReplyDelete
  12. The bookmarklet on this page:

    jQuery event tracer

    will log jQuery events for the page you are viewing to the console.

    ReplyDelete
  13. I also found jQuery Debugger in the chrome store. You can click on a dom item and it will show all events bound to it along with the callback function. I was debugging an application where events weren't being removed properly and this helped me track it down in minutes. Obviously this is for chrome though, not firefox.

    ReplyDelete