jquery .off(): how to remove a certain click handler only?

The .off(); method allows you to target multiple selectors as well as a specific event.

  • $('.pippo').off() would remove all events for the .pippo selector.
  • $('.pippo').off('click') would remove all click events for the .pippo selector.
  • $('.pippo').off('click', handler) would remove all click events with that handler for the .pippo selector.

In your case the handler used to add the event listener was an anonymous function so the handlercannot be used in the off() method to turn off that event. That leaves you with three options, either use a variable, use a namespace or both.

Its quite simple to figure out which one to use.

if( "The same handler is needed more than once" ){
    // you should assign it to a variable,
} else {
    // use an anonymous function. 
}

if ( "I intent to turn off the event" && ( "The handler is an anonymous function" || "I want to turn off multiple listeners for this selector at once" ) ){
    // use a namespace
} 

In your case

  • your handler is only used once so your handler should be an anonymous function.
  • you wish to turn off the event and your handler is anonymous so use a namespace.

So it would look like this

$('.pippo').on('click.group1', function () {
    alert("pippo");
});

$('.dai').on('click', function () {
    $('.pippo').off('click.group1');
    alert("ok, removed");
});

It would work just as well to assign you handler to a variable if you prefer. This allows you to specify which selector, eventType and handler to remove.

var pippo_click = function (e) {
    alert("pippo");
});

$('.dai').on('click', function () {
    $('.pippo').off('click', pippo_click);
    alert("ok, removed");
});

But as a rule you shouldn't create variables if they're not needed.


Because you are calling .off for click event. It is removing all possible click events on that selected element. The trick is to define a handler and remove that particular handler only.

function showPluto() {
  showMsg("pluto");
};

function showPippo() {
  showMsg("pippo");
};

function showMsg(text) {
  alert("showMsg called with text: " + text);
};

$('.pippo').on('click', showPippo);
$('.pluto').on('click', showPluto);

$('.dai').on('click', function() {
  $('.pippo').off('click', showPippo);
  alert("ok, removed");
});

One easier alternative with jQuery is to define a namespace for your click events:

$('.pippo').on('click.first', ...);
$('.pluto').on('click.second', ...);

// Remove only the pippo listener
$('.pippo').off('click.first');

Note that your classes pippo and pluto refer to the same element so using one or the other will not change anything.

https://jsfiddle.net/6hm00xxv/2/


Ok, solved. I just had to bind the handler to document:

function showMsg(text) {
    alert("showMsg called with text: " + text);
};

$(document).on('click', '.pippo', function () {
    showMsg("pippo");
});


$(document).on('click', '.pluto', function () {
    showMsg("pluto");
});

$('.dai').on('click', function () {
    $(document).off('click', '.pippo');
  alert("ok, removed");
});

https://jsfiddle.net/6hm00xxv/1/