Tag Archives: order

Reorder JQuery event handlers

I was little bit suprised when I didn’t find in JQuery an ability to bind event’s handler before than already binded event’s handlers list. Yes, it is possible to first attach our handler rather than others, but this may be very difficult sometimes. So I spent some time looking through JQuery sources and found what I need:

/*
 * A number of helper functions used for managing events.
 * Many of the ideas behind this code originated from
 * Dean Edwards' addEvent library.
 */
jQuery.event = {
 
    // Bind an event to an element
    // Original by Dean Edwards
    add: function( elem, types, handler, data ) {
        ...
 
        // Init the element's event structure
        var elemData = jQuery.data( elem );
 
        // If no elemData is found then we must be trying to bind to one of the
        // banned noData elements
        if ( !elemData ) {
            return;
        }
 
        // Use a key less likely to result in collisions for plain JS objects.
        // Fixes bug #7150.
        var eventKey = elem.nodeType ? "events" : "__events__",
            events = elemData[ eventKey ],
            eventHandle = elemData.handle;
 
        ...
 
        while ( (type = types[ i++ ]) ) {
            ...
 
            // Get the current list of functions bound to this event
            var handlers = events[ type ],
                special = jQuery.event.special[ type ] || {};
 
            ...
 
            // Add the function to the element's handler list
            handlers.push( handleObj );
 
            ...
        }
 
        // Nullify elem to prevent memory leaks in IE
        elem = null;
    }
 
    ...
}

As we can see from this code all we need to do is get “handlers” array (for “click” event in this example) from target element. Then we can do anything we need with event’s handlers. Code to do this is quite simple:

var
elementData = jQuery.data(targetElementDom),
events = (elementData.events ? elementData.events : elementData.__events__),
handlers = events['click'];
 
// Only one handler. Nothing to change.
if (handlers.length == 1) {
    return;
}
 
// Insert last handler at first index.
handlers.splice(0, 0, handlers.pop());

I used previous code to attach confirm window to elements which already have (or not) “click” event handlers.

Little demo.