Inspecting And Reusing jQuery Events

Adding events to HTML elements with jQuery is pretty simple, but I found that extending those events wasn't an easy task. I was faced with an issue where I had some third party code that performed an action on an element, and I needed to add an event and call the same handler from that event. As this was within a CMS I had limited scope to just add my new event to the existing code, so I needed a way of pulling out the current jQuery events and then calling that event handler separately. This post looks at how I accomplished this.

Let's start with a couple of simple form input elements.

<input type="text" class="field-text" />
<input type="text" class="field-next" />

As an example that can be useful here I'm going to set up a 'change' event that will copy the text entered into field-text into the field-next. This is a simple enough example and doesn't require that much code.

var fieldtext = $(".field-text");
var fieldnext = $(".field-next");

var copytext = function() {
  fieldnext.val(fieldtext.val());
};

fieldtext.on("change", function(event) {
  copytext();
});

With the event setup we can then use jQuery to extract the events into a variable. To extract the event data out of the field we need to use a somewhat undocumented function called _data. This function accepts the element and the type of data we are trying to retrieve, in this case we pass 'events' to get the events data.

var events = $._data(fieldtext[0], "events");

The 'events' variable now contains all of the events associated with this element. What I want to add to this was a 'keyup' event so that when the user stopped typing we would wait for 1 second before calling a function called 'doneTyping'. If the user resumes typing we would just restart the counter. This sort of technique is useful in search suggestions or other network related lookups where you need a second in order to retrieve the content. By delaying the lookup slightly a better user experience is created where they aren't seeing things pop in and out whilst they are typing.

var typingTimer;
var doneTypingInterval = 1000;
fieldtext.on("keyup", function(event) {
  clearTimeout(typingTimer);
  typingTimer = setTimeout(doneTyping, doneTypingInterval, event);
  return false;
});

The final step here is to call the original event handler. What we do here is pull up the events list we created before and run the handler function that exists on every change event found. We also pass in the current event parameter to ensure that the event handler is called in the same way that an event handler would call it.

function doneTyping(event) {
  $.each(events.change, function() {
    this.handler(event);
  });
}

This effectively means that the change and keyup events are running the same code, but we have gone about it in a little bit of a circuitous route due to the limitations of the platform.

If you want to see all of this code in action then I have created a CodePen that contains all of the code above.

Add new comment

The content of this field is kept private and will not be shown publicly.
CAPTCHA
1 + 1 =
Solve this simple math problem and enter the result. E.g. for 1+3, enter 4.
This question is for testing whether or not you are a human visitor and to prevent automated spam submissions.