Namespaced Events in jQuery

Published by Chris Coyier

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!

Want to learn more about jQuery? I have a complete course available.