Why bind and unbind don't work as expected
Question by Ayen
I was originally doing this:
$('div.ocontainer').each(function() {
var o = $(this);
var newCode = $(this).attr('id');
if (o.parents('.ocontainer').length != 0) {
var oldCode = o.parents('.ocontainer').attr('id');
console.log('unbinding '+oldCode);
$('#'+oldCode+' a').each(function() {
$(this).unbind('click')
})
}
console.log('binding '+newCode);
$('#'+newCode+' a').each(function() {
$(this).click(function() {
decideStMethod(newCode);
})
})
})
…but the unbind
was not working. I ended up with the original code being passed in the click function. So I changed to using name spaced events:
$('div.ocontainer').each(function() {
var o = $(this);
var newCode = $(this).attr('id');
if (o.parents('.ocontainer').length != 0) {
var oldCode = o.parents('.ocontainer').attr('id');
console.log('unbinding '+oldCode);
$('#'+oldCode+' a').each(function() {
$(this).unbind('click.'+oldCode)
})
}
console.log('binding click.'+newCode);
$('#'+newCode+' a').each(function() {
$(this).bind('click.'+newCode,function() {
decideStMethod(newCode);
})
})
})
…and now the unbind
works but the subsequent bind
does not. Note, though, that the line that is doing the bind
DOES work if it’s not subsequent, that is, if it is not preceded by an unbind
.
The use of this is that first a region of the page is processed, and the binding is done on the links within it. Then, the subregions are processed, and if one of them has its own code, the region’s handler must be unbound and replaced with the subregion’s. The reason for all of this is that the subregions are placed in the region dynamically, so what they will be is never known in advance. Oh, and just in case it matters, this is jQuery 1.72
So:
<div id="region" class="ocontainer">
<div id="subregion" class="ocontainer">
<a>
On the processing of region, the link is bound to click.region and a function passing ‘region’. Then, click.region should be unbound, which it is, and click.subregion bound in its place with a function passing ‘subregion’, which does not happen.
Answer by Starx
First thing is first, bind()
and unbind()
are deprecated functions. Use .on()
and .off()
instead.
Here is an example with some improvements too.
$('div.ocontainer').each(function() {
var o = $(this);
var newCode = o.attr('id'); //Use cached version instead
if (o.parents('.ocontainer').length != 0) {
var oldCode = o.parents('.ocontainer').attr('id');
console.log('unbinding '+oldCode);
$('#'+oldCode+' a').each(function() {
o.off('click', "#"+oldCode); //Turn off the event handler
})
}
console.log('binding click.'+newCode);
$('#'+newCode+' a').each(function() {
$(this).on('click', "#" + newCode, function() {
decideStMethod(newCode);
})
})
})