I'm talking about the following:
.unbind().click(function () {
// Do something
}
It looks a bit dodgy to me, however it makes sense: the developer wants to first remove any events bound to the element and then bind a click event.
Is there a better solution for this issue? Or correct my way of thinking.
I'm talking about the following:
.unbind().click(function () {
// Do something
}
It looks a bit dodgy to me, however it makes sense: the developer wants to first remove any events bound to the element and then bind a click event.
Is there a better solution for this issue? Or correct my way of thinking.
Share Improve this question edited Dec 25, 2020 at 16:53 Brian Tompsett - 汤莱恩 5,89372 gold badges61 silver badges133 bronze badges asked Aug 21, 2012 at 7:30 Jackie ChanJackie Chan 2,6626 gold badges36 silver badges71 bronze badges5 Answers
Reset to default 9It's not really good practice, because you do not control which click events get unbound. There are two different approaches to improve this:
Use event namespaces (faster)
You can use a namespace to control you unbind just the click event you're going to bind again:
$(selector).off('click.namespace').on('click.namespace', function(e) { //...
Use classes (fastest)
Use classes added to the link to mark it as registered (this does not unbind previously bound events, but it helps preventing multiple event bindings, which is the issue in most cases you would use off
(unbind) before on
(bind):
$(selector).not('.registered').addClass('registered').on('click', function(e) { //...
You can even turn this into a little sexy plugin, writing:
$.fn.register = function(register_class) {
register_class || (register_class = 'registered'); // lets you control the class
return this.not('.' + register_class).addClass(register_class);
};
Like this, you can just call register
on every selector:
$(selector).register().on('click', function(e) { //...
Or with a specific class, if «registered» is taken:
$(selector).register('special_handler_registered').on('click', function(e) { //...
Performance?
If you wonder about the performance of the different handlers:Check out this performance test here
I followed this approach whenever I had to "renew" some button, link, ect., behavior, and I think there's nothing wrong with it. But be aware that with your code you'd be removing every handler attached to the element(s). So, instead:
$(selector).unbind('click').click(function(){
// do something
})
Well, at least it is good practice to specify which event handlers should be unbinded. So if there was some click event hendler and we want to unbind only it, then we can use unbind('click')
.
As there can be some other handlers in addition to yours, it make sense to use namespaces.
$(selector).off('click.myns').on('click.myns', function() {....})
or
$(selector).unbind('click.myns').bind('click.myns',function() {...})
This way you will only touch your own handler and not some others, for instance added by jquery plugins
I usually try to used named event functions where ever possible in order to be able to unbind them explicitly:
$('a').unbind('click.myfunc').bind('click.myfunc', function(evt) { ... });
This way you could add this binding to an init-function that could be executed multiple times (handy for situations where you can't use delegate for whatever reason).
In general I would't try to unbind every event or even every handler of a certain event if I don't need to.
I'm also trying to stay current and replace all the bind/unbind calls with on/off ;-)