How to debug JavaScript / jQuery event bindings with Firebug or similar tools?

240,558

Solution 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).

  • jQuery 1.8.x

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

Solution 2

There's a nice bookmarklet called Visual Event that can show you all the events attached to an element. It has color-coded highlights for different types of events (mouse, keyboard, etc.). When you hover over them, it shows the body of the event handler, how it was attached, and the file/line number (on WebKit and Opera). You can also trigger the event manually.

It can't find every event because there's no standard way to look up what event handlers are attached to an element, but it works with popular libraries like jQuery, Prototype, MooTools, YUI, etc.

Solution 3

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.

Solution 4

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/

Solution 5

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

More detail in this Stack Overflow question

Share:
240,558
Jaanus
Author by

Jaanus

Design-driven engineer. iOS. Mac. Web frontend and some backend. Pixel pushing. Gestures, animations, transitions.

Updated on July 08, 2022

Comments

  • Jaanus
    Jaanus almost 2 years

    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 or ideas? Ideally, I would just like to see and edit events bound to elements, similarly to how I can edit DOM today.

  • Matthew Flaschen
    Matthew Flaschen over 12 years
    Note that since this runs in content JavaScript, it gets its data by querying JavaScript libraries. So it will only show events added with a supported library (which includes jQuery).
  • Ruan Mendes
    Ruan Mendes over 12 years
    FYI: This will not display events that weren't attached with jQuery
  • thepeer
    thepeer over 12 years
    Totally agree about console.log(), however it should be hedged with something like if (window.console) in case it gets left in the code (much easier to do than with alert()) and breaks IE.
  • Andrew
    Andrew over 12 years
    @thepeer Personally I prefer to do a check for the console at the start of the file, and if it doesn't exist create a dummy object.
  • Maarten Kieft
    Maarten Kieft about 12 years
    That plugin has 1 really big downside: When you are debugging, and you want to inspect the value of a variable which contains a jquery collection you are not able to inspect the value when your code is paused. This is not the cause with firebug. The reason for me to uninstall it. alone
  • Corey O.
    Corey O. over 11 years
    Below is a similar snippet for debugging all events (please excuse the lack of formatting): $('#foo').click(function(event) { var events = $(this).data('events'); $.each(events, function(event, handlers) { $.each(handlers, function(key, handlerObj) { console.log("--------------------------------------"); console.log(event+"["+key+"] | "+handlerObj.handler) ; }); });
  • BrainSlugs83
    BrainSlugs83 over 11 years
    So how do you do it with events that weren't attached with jQuery?
  • Crescent Fresh
    Crescent Fresh over 11 years
    @BrainSlugs83: see the linked answer in this answer. (tl;dr: you can't).
  • Eli
    Eli over 10 years
    console.debug() will write in the debug console
  • derloopkat
    derloopkat over 9 years
    This feature was released and included into FireBug 2.0.1. Now when you inspect a HTML element on a page, there is a new "Events" panel where you can see attached events and their handlers.
  • Matty J
    Matty J over 9 years
    FireQuery doesn't seem to show attached events anymore :(
  • Erick Asto Oblitas
    Erick Asto Oblitas about 8 years
    @CrescentFresh How if I want to know where was attached $('#foo').click(function() { console.log('clicked!') });
  • Fla
    Fla almost 8 years
    And for Firefox, instructions are on MDN
  • chukko
    chukko over 7 years
    Unfortunately this doesnt work well for locating inherited listeners.