jQuery Custom Events

|   Apr 9, 2013

Overview

In the last article about unobtrusive JavaScript, we learned how to use event delegation and markup-driven behavior to create reusable JavaScript components. This article will explore how to use custom events in jQuery to give the developer even greater control over the component’s behavior.

While many facets of an unobtrusive widget can be controlled via the markup (data attributes), we can expose even more to the developer by triggering custom events. These events are fired on the DOM just like normal browser events, with the same bubbling characteristics. In jQuery, it’s as simple as this:

$tab.trigger('show.tab');

In this case, we’re triggering a custom show event (namespaced as show.tab) on the tab element.

Notifications

The primary purpose of a custom event is to notify you that something interesting just happened. The widget author decided on the things that she thought you might like to know about, and will trigger an event for you. Using the tab widget example, it could let you know when it was loaded, when a tab is selected, etc. These events are broadcast to give you the opportunity to create your own custom code to react to those events. Reacting to specific events with standalone event-handlers will allow you to decouple related plugins and avoid a tangled mess of nested callbacks.

Namespaced events

Did you notice the “.tab” suffix of the event name in the example above? jQuery provides a mechanism to namespace your custom events, so that you can:

  1. Provide a more descriptive and specific event name
  2. Avoid conflicts with other events with the same name.
  3. Easily unbind all events for a given namespace.

Even though you may add a namespace to your events, you should still choose an event name that is unique, beause jQuery will try to call a method on the element with that same name (i.e. click). Unexpected things could happen if the event name is too generic!

Bubbling

When a widget fires a custom event on a specific DOM element, they will bubble up to the document, so you can listen for those events in a single location. Starting with the triggering element, event-handlers will be executed in the order that they were bound, eventually ending up at the document level. Based on the techniques that were discussed in the last article, you can write your own event-handler that will listen for these custom events in an unobtrusive fashion:

$(document).on('selected.tab', '.tab', function(){
  // this === the element with a class of "tab"
});

Listening for events at the document level is probably the most important thing you can do to make your JavaScript unobtrusive. No more searching for elements on DOM-ready; you just sit back and react only when that particular event occurs!

Responding to events with results

Besides being simply notified of an event, you can also return a value from an event-handler to alter its behavior. Having a bound event-handler return false is a common way of allowing a widget to prevent something from happening. In this case, we’ll ask for confirmation before allowing the tab with a class of “special” to be shown:

$(document).on('beforeshow.tab', '.special', function(){
  return confirm('Are you ready to show this special tab?');
});

Since we need to know the value returned from the event handler, we have to trigger the event using an event object instead of an event name string. Triggering an event using an event object created with $.Event() will let you inspect the returned value from the last-encountered event-handler (before propagation was stopped). The returned value will be populated in the result property of the event object:

var beforeShowEvent = $.Event('beforeshow.tab');
$tab.trigger(beforeShowEvent);

if (beforeShowEvent.result !== false) {
  // show the tab
}

 

Not just the DOM

Custom events don’t always have to be triggered on the DOM. jQuery also lets you trigger events on any JavaScript object. For example, you could publish events on your own JavaScript app (a singleton perhaps, likejQuery), for any subscribers to respond to. Just pass the object as the selector to jQuery, then trigger the event like you normally would:

window.myApp = {
  doSomething: function(){

    // Broadcast event
    $(myApp).trigger('somethingInteresting');
  }
};

// Listen for event
$(myApp).on('somethingInteresting', function(e){

});

In this case, bubbling obviously does not apply since it has nothing to do with the DOM, but it gives you a nice way to publish and subscribe to events in your app.

Conclusion

Custom events can really help you decouple the individual components in your application. Each JavaScript component can remain independent, without worrying about where or how it is used. And your components can start to build off of each other, communicating to each other via custom events.

At Socialcast, we found that almost all JavaScript widgets could define an API, which included the custom events that they might trigger. This event API helped us to figure out how our widgets could work together. For example, we wanted our (HTML5) autofocus polyfill to also work inside of a modal (dialog). By default, the autofocus search waited for the document ready event, but by also listening for the custom contentload event triggered by the modal widget, we were able to utilize it in both scenarios, without tightly coupling the two components.

Comments

  • thanks!!!

    Commented on June 19, 2013 at 6:52 am
  • This was very helpful, read a dozen articles on custom events but hadn’t seen a simple example of the “responding with results” use case. That’s exactly what I needed to write an “updateContent.modal” event in a modal plugin I’m developing.

    Commented on January 24, 2014 at 7:31 pm
  • Thanks for this post. It clarifies a few questions I had about using a custom event model with jQuery.

    Commented on February 27, 2014 at 11:27 am

Leave a comment

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

Connect with Facebook

Sign up to receive email communications regarding events, webinars, and product news.

What is Socialcast?

Socialcast by VMware (NYSE: VMW) is a social network for business uniting people, information, and applications with its real-time enterprise activity stream engine. Behind the firewall or in the cloud, Socialcast enables instant collaboration in a secure environment. Socialcast is headquartered in San Francisco, California. www.socialcast.com