Tengo un elemento con dos controladores vinculados:

<button class="pippo pluto">
  push me
</button>

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


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

Estoy tratando de .off () solo uno de ellos, pero la sintaxis me elude :-( Estoy tratando con algo entre la línea de ...

<button class="dai">
  remove
</button>

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

Pero esto elimina tanto el controlador. Así que estoy intentando con ...

$('.pippo').off('click .pippo');

Pero luego nada se elimina.

Entonces eliminé el espacio medio:

$('.pippo').off('click .pippo');

Pero de vuelta al cuadro 1: ambos manejadores se eliminan.

La sintaxis correcta sería entonces ...?

https://jsfiddle.net/6hm00xxv/

17
Dr. Gianluigi Zane Zanettini 13 may. 2016 a las 11:59

4 respuestas

La mejor respuesta

El método .off(); le permite apuntar a múltiples como lo hará un evento específico.

  • $('.pippo').off() eliminaría todos los eventos para el selector .pippo.
  • $('.pippo').off('click') eliminaría todos los eventos click para el .pippo
  • $('.pippo').off('click', handler) eliminaría todos los eventos click con ese controlador para el selector .pippo.

En su caso, el handler utilizado para agregar el detector de eventos era una función anónima, por lo que handler no se puede utilizar en el método off() para desactivar ese evento. Eso te deja con tres opciones: usar una variable, usar un espacio de nombres o ambos.

Es bastante sencillo averiguar cuál usar.

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
} 

En tu caso

  • su controlador solo se usa una vez, por lo que debe ser una función anónima.
  • desea desactivar el evento y su controlador es anónimo, así que use un espacio de nombres.

Entonces se vería así

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

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

Funcionaría igual de bien asignarle su controlador a una variable si lo prefiere. Esto le permite especificar qué selector, eventType y controlador eliminar.

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

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

Pero, por regla general, no debe crear variables si no es necesario.

22
TarranJones 13 may. 2016 a las 11:20

Una alternativa más fácil con jQuery es definir un espacio de nombres para sus eventos de clic:

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

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

Tenga en cuenta que sus clases pippo y pluto se refieren al mismo elemento, por lo que el uso de uno u otro no cambiará nada.

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

3
floribon 13 may. 2016 a las 09:09

Ok, resuelto. Solo tuve que vincular el controlador para documentar:

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/

1
Dr. Gianluigi Zane Zanettini 13 may. 2016 a las 09:04

Porque estás llamando a .off para el evento click. Está eliminando todos los posibles eventos de clic en ese elemento seleccionado. El truco consiste en definir un controlador y eliminar solo ese controlador en particular.

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");
});
1
Yahya 13 may. 2016 a las 09:06