jQuery - Event Namespacing

jquery-event

What is event namespacing?

A namespace provides context for events. The custom events, collapse and expand, are ambiguous. Adding a namespace to a jQuery custom event provides context for events. Then namespace is appended to the name of the event, separated by a dot. We’ll make our namespace called TreeEvent, because our events represent the actions and functionality of a tree folder structure. Once we’ve added the namespaces to our events, the code will now look like so

    $("#tree li:parent").bind("collapse.TreeEvent", function(evt) {
        if(evt.target == evt.currentTarget)
        {
            $(evt.target).children().slideUp().end().addClass("collapsed");
        }
    }).bind("expand.TreeEvent", function(evt) {
        if(evt.target == evt.currentTarget)
        {
            $(evt.target).children().slideDown().end().removeClass("collapsed");
        }
    }).toggle(function() {
        $(this).trigger("collapse.TreeEvent");
    }, function() {
        $(this).trigger("expand.TreeEvent");
    });

All we needed to change were the event names in the .bind() and .trigger() methods for both the collapse and expand events. We now have a functional example using custom namespaced events.

Namespace are useful when authoring plugins and third-party components. If needed, the user of your plugin can effectively disable your plugin by unbinding all event handlers that it's registered.

How can we add a namespace to an event?

To add a namespace when registering an event handler, simply suffix the event name with a period and then your unique namespace (e.g. '.fooPlugin'):

jQuery.fn.foo = function() {

    this.bind('click.fooPlugin', function() {
        // do stuff
    });

    this.bind('mouseover.<wbr>fooPlugin', function() {
        // do stuff
    });

    return this;
};

// Use the plugin:
jQuery('a').foo();

How can we unbind all event handlers within a given namespace?

// Destroy its event handlers:
jQuery('a').unbind('.fooPlugin');
$("#tree li:parent").unbind("collapse.TreeEvent"); // just remove the collapse event
$("#tree li:parent").unbind(".TreeEvent"); // remove all events under the TreeEvent namespace

How can we unbind all event handlers in a namespace on an element, regardless of event type?

$('#foo').unbind('.mynamespace');

What is the benefit of using namespaced event?

Using namespaced event allows us to unbind or trigger some events of a type without affecting others. For example, you are the author of a plugin. On a page where your plugin is being used, the user may have an event handler attached to an element, which your plugin also attach to. You may want to trigger an event on that element (to invoke your handler), without invoking the other handler.

Also, as an author of a plugin, you may find yourself needing to unbind your handler, without unbinding other handlers. You can do this safely using namespace.

What is namespaced event?

Generally, when binding an event handler, you would do something like:

$('.class').bind('click',function(){});

However, sometimes, you want to unbind just a specific handler, or group of handlers (for example, all handlers bound by a plugin). Unfortunately, calling unbind:

$('.class').unbind('click');

will remove all bound handlers.

jQuery provides a concept called namespaced events. Simply add a namespace name (which can be the name of your plugin) to your event when you declare it. You can then reference that namespaced event both with unbind and trigger:

$('.class').bind('click.namespaceName',function(){});
$('.class').trigger('click.namespaceName');
$('.class').unbind('click.namespaceName');

Namespaced events will be unbound or triggered when their namespace is mentioned explicitly, or no namespace is mentioned at all.

If you've used the same namespace on multiple events, you can easily remove the bindings from all events at once:

$('.class').bind('click.namespaceName', function(){});
$('.class').bind('blur.namespaceName', function(){});
$('.class').unbind('.namespaceName');

Can we use multiple namespaces on our events?

Yes. As of jQuery 1.3, we can use multiple namespaces on our events:

$('.class').bind('click.a.b'), function(){});
$('.class').trigger('click.a');
$(.class').unbind('click.b');
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License