Events in Javascript are often seen as a bit of an enigma. This is odd given that Javascript is very much an event driven language, but it is typically down to their complex nature and difficulty to debug. To this end I've createdto help track events which are subscribed to DOM nodes.

Introduction

When working with events in Javascript, it is often easy to lose track of what events are subscribed where. This is particularly true if you are using a large number of events, which is typical in a modern interface employing progressive enhancement. Javascript libraries also add another degree of complexity to listeners from a technical point of view, while from a developers point of view they of course can make life much easier! But when things go wrong it can be difficult to trace down why this might be.

It is due to this I've put together a Javascript bookmarklet called Visual Event which visually shows the elements on a page that have events subscribed to them, what those events are and the function that the event would run when triggered. This is primarily intended to assist debugging, but it can also be very interesting and informative to see the subscribed events on other pages.

Usage

Using Visual Event on any web-page is extremely simple:

Drag the Visual Event link below to your bookmark bar:



link below to your bookmark bar: Load a web-page which uses one of the supported Javascript libraries

Click Visual Event in your bookmark bar

in your bookmark bar View the event handlers which are attached to the document elements.

You can see a demo of this in action showing the events attached by my own DataTables jQuery plugin.

Visual Event is currently beta level software and as such there are a few important notes to make. This first of these is that Visual Event will not currently work in Internet Explorer. IE has it's own events model and I've concentrated initially on the W3C model. The second point is that only events added by libraries which Visual Event recognises will actually be shown (see later for why). The currently supported libraries are:

DOM 0 events

jQuery 1.2.x +

YUI 2.6.x (2.x might work!)

MooTools 1.2.x

Prototype 1.6.x

JAK (Events 2.2)

Glow

When using Visual Event you will notice that I've used colour coding and icons to represent different actions in a concise and easy to view manner. The background colours which show that an element has an event attached to it follow the mapping shown below.

Colour Meaning Blue Mouse event Red UI event (keys etc) Yellow HTML event (select etc) Purple Mouse + UI events Orange UI + HTML events Green Mouse + HTML events Black Mouse + UI + HTML events

The icons representing individual events also follow this colouring pattern, but also indicate what the attached event is pictorially. The follows the mapping shown below.

Icon Event click dblclick mousedown mousemove mouseout mouseover mouseup change focus blur select submit keydown keypress keyup load unload custom / unknown

Technical information

It turns out that there is no standard method provided by the W3C recommended DOM interface to find out what event listeners are attached to a particular node. While this may appear to be an oversight, there was a proposal to include a property called 'eventListenerList' (reference) to the level 3 DOM specification, but this has unfortunately been removed in the latest drafts. As such we are forced to looked at the individual Javascript libraries, which typically maintain a cache of attached events (so they can later be removed and perform other useful abstractions).

In the current version of Visual Event I have included support for jQuery, YUI, MooTools, Prototype (many thanks to John Schulz for his advice in adding Prototype support) and JAK (with thanks to Michal Aichiner for providing an API function). I've investigated including information Dojo, however this library does not appear not to cache the information that is required by visual event. If anyone does know of a way - please get in touch!

I would strongly encourage developers who use some of the other libraries to get in touch with me, and submit a function which can be used by Visual Event to parse a specific library's cache. The following structure must be returned by the function:

// Return code from event cache parsing function [ { // Node which is in question "nNode": -, // The name of the library where the event comes from (e.g. 'YUI') "sSource": '', // Array of the listeners attached to this node "aListeners": [ { // Type of event (e.g. 'click') "sType": '', // String of the function to run (from Function.toString()) "sFunction": '', // Indicate if the event has been removed by the library - typically false "bRemoved": '' }, ... ] }, ... ]

Alternatively, you can make use of a global variable which Visual Event will recognise. This global variable is called VisualEvents which you can populate using either the structure given above, or the slightly simpler version below (ideal for putting into an event registration function) - or any combination of the two:

[ { // Node which is in question "nNode": -, // The name of the library where the event comes from (e.g. 'YUI') "sSource": '', // Type of event (e.g. 'click') "sType": '', // String of the function to run (from Function.toString()) "sFunction": '', // Indicate if the event has been removed by the library - typically false "bRemoved": '' }, ... ]

Future work

There is quite a lot which could be done with Visual Event in order to improve it and make it more useful for developers. The following is my current list (and in no particular order!):

Support for Internet Explorer

Add parsers for other Javascript libraries

Improve the UI look and feel

IIf you have any other ideas, or if you are interested in helping me develop Visual Event further, please don't hesitate to get in touch!