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.

6 thoughts on “Reorder JQuery event handlers

    1. Alexander Shchekoldin Post author

      Thanks for your comment! Yes, it doesn’t work for now, but you can use something like this:

      $(selector).each(function() {
          var
          elementData = jQuery._data(this),
          events = elementData.events;
      
          var onClickHandlers = events['click'];
      
          // Only one handler. Nothing to change.
          if (onClickHandlers.length == 1) {
              return;
          }
      
          onClickHandlers.splice(0, 0, onClickHandlers.pop());
      });
      
      Reply

Leave a Reply

Your email address will not be published. Required fields are marked *