Namespace Your Events

A common pattern in jQuery plugin development is the need to undo what the plugin has done. This is usually handled through a method prefixed with "un". Another common pattern is the use of anonymous functions for event handlers. Unbinding events is easy with jQuery but unbinding a single event handler requires the use of a named function. jQuery 1.2 now provides another option for binding and unbinding events: event namespaces.

A Plugin

As a very simple example, let's say I wrote a plugin called "clicked". It provides two methods: clicked and unclicked. The clicked method attaches an event to all matched elements that when clicked adds a class name of "clicked" to the clicked element. The unclicked method removes the "clicked" classes it might have set and the clicked event handlers it attached. Here is the code:

JavaScript:
  1. (function($){
  2.     $.fn.extend({
  3.         clicked: function() {
  4.             return this.bind('click', function() {
  5.                 $(this).addClass('clicked');
  6.             });
  7.         },
  8.         unclicked: function() {
  9.             retun this.removeClass('clicked').unbind('click');
  10.         }
  11.     });
  12. })(jQuery);

You could use the plugin by calling it like this:

JavaScript:
  1. $('div').clicked();

And if you wanted to stop using the plugin, you could just call unclicked:

JavaScript:
  1. $('div').unclicked();

So far, so good.

A Problem

But let's say I'm also using another plugin that attaches a click event to the same elements that the clicked plugin does. Calling unclicked would unbind all the click events, including those bound by your own code or another plugin.

A Solution: Event Namespacing

Event namespacing provides a way to manage specific event handlers. For example, a plugin could namespace its event handlers to make them easier to unbind while still using anonymous functions. To namespace an event, just suffix the event type with a period and a name ("type.namespace").

Here is the clicked plugin again, but this time using event namespaces:

JavaScript:
  1. (function($){
  2.     $.fn.extend({
  3.         clicked: function() {
  4.             return this.bind('click.clicked', function() {
  5.                 $(this).addClass('clicked');
  6.             });
  7.         },
  8.         unclicked: function() {
  9.             retun this.removeClass('clicked').unbind('click.clicked');
  10.         }
  11.     });
  12. })(jQuery);

Now it only unbinds the events that it bound in the first place, leaving any other bound events alone.

10 Responses to “Namespace Your Events”

  1. AD Says:

    Please could you have more tutorials on how to integrate jQuery with PHP/MySQL -- perhaps a project, like a simple customer add/edit/delete/search/paging project, which includes auto-complete?

    Many thanks.

  2. John Resig Says:

    Great write-up Karl! I actually did my first bit of real-world "event namespacing" the other day when I add a new .unmask() method to the Masked Input plugin. It was a super-simple set of changes but worked wonderfully!

  3. John Resig Says:

    Oooops! I meant Brandon - great job!

  4. Stan Says:

    Thanks for the info here, I was trying to lookup info on the namespaces this morning and couldn't find any on the jQuery website except the reference in the changelog. Keep up the good work with your blog. Pax.

  5. Thomas Says:

    Super just what I needed... !!

  6. Kevin Says:

    I'm just begin to use JQuery, Thanks for the info!

  7. Joshua Says:

    It's good,
    Hope that the exchange links.
    Joshua's Blog
    http://www.joshua.org.cn

  8. bratz games Says:

    thanks for this great information on Namespace events

  9. Nanda Says:

    First I would like to congradulate you on this blog and I have found the writeup useful.

    However I have a problem where I bind a click function to the entire document but then want to unbind for a specific element in this case a textarea so that clicks inside the textarea do not trigger the anonymous function. Could using namespace s solve the problem.

    I have provided the jQuery code I am using to tdo this below:

    
    entire_document.bind('click', function(e)
    	{
    		jQuery('#textareaid').unbind('click');
                     if (condition)
                     {
                            // do some stuff
                      }
                     else
                      {
                             // do some other stuff
                       }
            entire_document.unbind('click');
    	});
  10. Karl Swedberg Says:

    Hi Nanda,

    Try something like this:

    $('body').bind('click', function(e) {
      if (e.target.nodeName != TEXTAREA) {
        // do something
      }
    });

    No need for the unbind.

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <pre> <em> <i> <li> <ol> <strike> <strong> <ul>

IMPORTANT: If you wish to post code examples, please wrap them in <code> tags. Multi-line code should be wrapped in <pre><code> </code></pre> Also, use &lt; instead of < and &gt; instead of > in the examples themselves. Otherwise, you could lose part of the comment when it's submitted.