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.