It’s really easy to add an event listener in jQuery. It’s equally easy to remove an event listener. You might want to remove a listener because you don’t care to perform any actions on that event anymore, to reduce memory usage, or both. But let’s say you’ve attached several listeners to the same event. How do you remove just one of them? Namespacing can help.
Let’s look at code.
$("#element")
.on("click", doSomething)
.on("click", doSomethingElse);
Both doSomething
and doSomethingElse
will fire when that element we’ve selected is clicked. That’s good. It’s one advantage of using jQuery to bind events rather than super old school onclick
which would overwrite previously declared event handlers.
Now let’s say you want to remove the first of those event listeners, the one that fires doSomething
. How do you do that?
$("#element").off("click");
Careful there, that will unbind both of those handlers which is not what we want.
Luckily jQuery will take the same second parameter with .off()
as it does with .on()
.
$("#element").off("click", doSomething);
That’s great if you have a reference to an actual function that you can pass in as that parameter. But what if you don’t have that reference? Either because you don’t know what it is or you used an anonymous function as the handler, like this:
$("#element")
.on("click", function() {
console.log("doSomething");
});
How do you unbind that one in a safe way that won’t accidentally unbind other click handlers? Namespaced events!
Instead of just click
as the name of the event, you can use click.namespace
.
$("#element")
.on("click.myNamespace", function() {
console.log("doSomething");
});
Now you can use .off()
with that exact event name to unbind just it.
$("#element").off("click.myNamespace");
Just one of those cool useful things in jQuery. Even with modern event binding using addEventListener
and removeEventListener
this would be a bit tricky (I think).
I used it recently in that bookmarklet I made to test line length. I essentially wanted to bind a mouseenter
event on every single element on the page (using delegation) and then when one is clicked, unbind both those events. But I wanted to be careful not to unbind anything that I didn’t bind myself. Hence, namespacing!
This also works with Zepto, and is incredibly helpful when you’re writing unit tests and need to clean up your objects for subsequent tests.
Shoosh, I knew about namespaces but honestly I didn’t think they were implemented natively in jQuery. I thought you had to manually add an event listener to use namespaced events in a plugin.
Thanks for the tip!
Another thing that’s cool about namespaces is that you can have multiple levels of them. For example, you could do:
$('.some-div').on('click.myPlugin.submitButtonClick', '.submit-button', handlerFunction)
so you could call .off() for all events in a namespace or just one of them.
This article should also mention about canceling all events from a namespace, which is very useful for jQuery plugins.
+1
It’s surprising that this little piece of info is so hard to find online. A little jsfiddle worked though, so I was looking for a place to verify whether my hunch was right about ONLY namespace being passed to unbind an event.
Thanks
I’ve been thinking about namespaces and wondering if there were a way to inject Geolocation into namespace so RSS feeds convert to GeoRSS. Is this something that can be achieved with jquery?
You can use
$("#element").on("click",function(){})
? I thought the only way was$("element").onclick(function(){});
. Any advantages of the former?I don’t think
onclick()
is a function in jQuery,click()
is though. The difference I believe ison()
will bind to elements whether they are present in the DOM or whether they are added dynamically at a later point in time.Not “onclick”, but “click”, which is a shortcut to the
on("click", function)
. Withon
you can attach multiple events –$(el).on("click focus", function (){});
, also you can create single event which will fire ife.target
is in event bubble, which gives you performance boost.$("table").on("click", "td", function () {});
– single event$("table td").click(function () {});
– amount of events == $(‘table td’).lengthAs mentioned there is support for this in Zepto too, but I’ve noticed you use the .MyNamespace for native events like
click.MyNamespace
orfocus.MyNamespace
, and custom events you use a reversed syntax:MyNamespace:eventName
.Seems that jQuery is smart enough to figure it out either way, but if you want it to work in both Zepto and jQuery you have to use the different syntax for custom events.
I fought this battle with Intimidatetime. So standard native events it uses
click.intimidatetime
, but for custom events I have to useintimidatetime:open
orintimidatetime:change
Thanks very much for that post. That will fix some problems I had in the past with some of my functions.
Hey Chris, can you post a snippet tutorial for the navbar animation as shown in Digitally Imported:
http://www.di.fm
Click on Channels.
I believe it’s jQuery UI but not sure.
Ah that’s awesome, going to try this asap.
Thanks!
:D
The two uses for this are if we don’t know the name of the function in question or an anonymous function has been used. However the only way to implement the namespace seems to be at the time of declaring the function, where you would be able to pass in a function with a name you know. It seems to be just an alternative method to passing in a function you have named? Are there any other uses for this that I am missing?
If you’re using proxies (
$.proxy
), and you need to detach them later, you either need to keep track of every proxy you create, or just use namespacing .This is terrific.
One thing that is very nice, but I had trouble with, is Dynamic Namspacing… below is how I prefer to bind events (in a
json
format):in this scenario I cannot make the name spaces dynamic, but in this next scenario I could create a dynamic namespace:
Dynamic namespacing can be really useful for plugins and such where you’d like to create > 1 instances of a plugin on a page, but not
unbind
all the other bindings whendestroy()
ing the plugin.Very nicely done. I am planning to access your jquery tutorials later this month.
Do you know if anyone has an example of using fittext for the text inside gridcells (kendoui jquery grid)