Is there a \"global\" unbind function in jQuery, such that I\'d be able to remove all bound events from a given namespace? eg:
// assume these are the events bou
You should add a class within the bind function
$('#foo').bind('click.myNS', ...).addClass('removeLater');
$('#bar').bind('keyup.myNS', ...).addClass('removeLater');
$('#baz').bind('dblclick.myNS', ...).addClass('removeLater');
and afterwards
$('.removeLater').unbind();
If #foo
#bar
and #etc
are all the same element or small set of them, you could also do:
$('div, button').unbind();
but if you have a bound event you don't want to remove that wouldn't be a good idea
You need to use jQuery's On and Off methods. Use document as the selector.
$(document).off('.myNS');
$(document).on('click.myNS','#foo', ...);
$(document).on('keyup.myNS','#bar', ...);
$(document).on('dblclick.myNS','#baz',''');
then your methods could look like
$(document).on('click.myNS','#foo', fooClicked);
var fooClicked = function(e){
var $this = $(e.target);
// do stuff
}
You need to hack into jQuery internals, here's a working demo of a simple implementation:
http://jsfiddle.net/nkMQv/1/
The main work is done in regular js loops and shouldn't be very inefficient as even this page contains ultimately only 106 items to loop through. You should of course use event delegation as much as possible to keep the amount of items in the jQuery handler collection as small as possible.
You could always wrap $.fn.bind and then cache the necessary refs:
(function ($) {
var origBind = $.fn.bind,
boundHash = {};
$.fn.bind = function (type, data, fn) {
var namespace = '',
events = [];
if (typeof type === 'string') {
// @todo check the allowed chars for event namespaces.
namespace = type.replace(/^[^.]+/, '');
if (namespace.length) {
events = boundHash[namespace];
// Namespaces can hold any number of events.
events = boundHash[namespace] = $.isArray(events) ? events : [];
// Only really need ref to the html element(s)
events.push({
type: type,
fn: $.isFunction(fn) ? fn : data,
that: this.length > 1 ? this.toArray() : this[0]
});
}
}
origBind.apply(this, arguments);
};
// namespace to be muffled. Feel free to qualify a specific event type.
$.muffle = function (namespace, type) {
var events = [];
if (boundHash.hasOwnProperty(namespace)) {
events = boundHash[namespace];
$.map(events, function (event) {
var _type = type || event.type;
if (event.type.indexOf(_type) === 0) {
$(event.that).unbind(_type, event.fn);
}
});
// @todo think of better return value.
return true;
}
// @todo think of better return value.
return false
};
})(jQuery);
You could add myNS
as a class to each of the elements where you want to unbind the events.
Truly you are looking for a magical global function but as always with magic you can only get illusion, in this case, of simplicity.
There is also jQuery solution using .live() or .delegate() (which is only variant of live()).
Using $("body").delegate("#foo", "click.myNs", func)
you also bind event and using $("#body").undelegate(".myNs")
you unbind it. I use here "body" element but ofcourse you can use any element that is ancestor of all elements you need binding on.
It will make your "unbinding" work faster but again it will make your events respond slower.