1

Have a look at http://jsfiddle.net/60j9hhz7/3/

UPDATED FIDDLE (use this) http://jsfiddle.net/60j9hhz7/10/

html:

<div class="mycontainer">
  <a href="#" class="test">test</a>   
</div><br/>
<a href="#" class="unbind">doesn't work</a><br />
<a href="#" class="unbind2">works</a><br />
<a href="#" class="unbind3">works too</a>

js:

$(document).on('click', '.test', function (e) {
  alert('hello');
});

$(document).on('click', '.unbind', function (e) {
  $(document).off('click', '.mycontainer a');
});

$(document).on('click', '.unbind2', function (e) {
   $(document).off('click');
});

$(document).on('click', '.unbind3', function (e) {
  $(document).off('click', '.test');
});

In the fiddle you'll see that the first off doesn't work (the alert still pops up) while all the others work.

Could somebody explain why this is and if there is a solution? I need to be able to target all links within a certain container but they may have hooked up their click events with different selectors.

Problem is unbind2 is too unspecific and unbind3 too specific

2
  • you are clearing click on a tag Commented Dec 3, 2015 at 12:44
  • yes, but why shouldn't this work? If I bind an event via on like that $(document).on('click', 'a', function() { $(this).css('color', 'red'); }) it does work Commented Dec 3, 2015 at 12:46

2 Answers 2

3

Here is the problem you need .off() to use the same selector as the bonded .on() event

$(document).on('click', '.test', function (e) {//see .test
  alert('hello');
});

$(document).on('click', '.unbind', function (e) {
  $(document).off('click', 'a');//will not work
});

$(document).on('click', '.unbind2', function (e) {
   $(document).off('click');
});

$(document).on('click', '.unbind3', function (e) {
  $(document).off('click', '.test');//will work
});

exp2:

$(document).on('click', '.mycontainer a', function (e) {
  alert('hello');
});

$(document).on('click', '.unbind', function (e) {
  $(document).off('click', '.mycontainer a');//will work 
});

$(document).on('click', '.unbind2', function (e) {
  $(document).off('click');
});

$(document).on('click', '.unbind3', function (e) {
  $(document).off('click', '.test');//will not work
});

http://jsfiddle.net/60j9hhz7/11/

Sign up to request clarification or add additional context in comments.

3 Comments

ok, so it's by design. Just to be clear: If I want to unbind an event I have to unbind on the jquery Object I bound it with the same selector? $(document) works while $('.test') doesnt. And this is the only way? Isn't there an easy way to just unbind every click event from a certain element? Like $('.test').off('click'); Beware: the code doesn't work, it's just an example
@Arikael No, there is no 'simple' way because this would bring many performance issues to handle it (processing element selector and comparing it to any ancestors handler matched selector) and could have many side effects. The easiest way could be just to use: $('.test').replaceWith(function () { return $(this).clone().on('click', function (e) { e.stopPropagation(); }); }); jsfiddle.net/60j9hhz7/12 This would unbind any event bound to element itself and avoid event to bubble through DOM, so not firing any delegated event
@Arikael This is more relevant example where this would have been an use case: jsfiddle.net/60j9hhz7/13
2

This is clearly (wait, could be quite ambiguous indeed...) explained in off() doc:

.off( events [, selector ] [, handler ] )

selector Type: String

A selector which should match the one originally passed to .on() when attaching event handlers

3 Comments

And .unbind2 does work because you're turning off all click events, regardless of selector
thanks for your answer, I chose madalin's answer as solution because he was a tad faster
@Arikael No problem, he gave relevant examples btw :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.