web-dev-qa-db-fra.com

Meilleur moyen de supprimer un gestionnaire d’événements dans jQuery?

J'ai un input type="image". Cela agit comme les notes de cellule dans Microsoft Excel. Si quelqu'un entre un numéro dans la zone de texte auquel ce input-image est associé, je configure un gestionnaire d'événements pour le input-image. Ensuite, lorsque l'utilisateur clique sur image, il obtient un petit menu contextuel pour ajouter des notes aux données.

Mon problème est que lorsqu'un utilisateur entre un zéro dans la zone de texte, je dois désactiver le gestionnaire d'événements input-image. J'ai essayé ce qui suit, mais en vain.

$('#myimage').click(function { return false; });
1027
the0ther

jQuery ≥ 1,7

À partir de jQuery 1.7, l’API d’événement a été mis à jour. .bind()/.unbind() sont toujours disponibles pour la compatibilité descendante, mais la méthode recommandée consiste à utiliser on () / off () fonctions. Le dessous serait maintenant,

$('#myimage').click(function() { return false; }); // Adds another click event
$('#myimage').off('click');
$('#myimage').on('click.mynamespace', function() { /* Do stuff */ });
$('#myimage').off('click.mynamespace');

jQuery <1.7

Dans votre exemple de code, vous ajoutez simplement un autre événement de clic à l'image, sans remplacer le précédent:

$('#myimage').click(function() { return false; }); // Adds another click event

Les deux événements de clic seront alors déclenchés.

Comme les gens l'ont déjà dit, vous pouvez utiliser unbind pour supprimer tous les événements de clic:

$('#myimage').unbind('click');

Si vous souhaitez ajouter un seul événement, puis le supprimer (sans en supprimer d'autres qui auraient pu être ajoutés), vous pouvez utiliser le suivi de nom d'événement:

$('#myimage').bind('click.mynamespace', function() { /* Do stuff */ });

et pour ne supprimer que votre événement:

$('#myimage').unbind('click.mynamespace');
1579
samjudson

Cela n'était pas disponible lorsque cette question a reçu une réponse, mais vous pouvez également utiliser la méthode live () pour activer/désactiver les événements.

$('#myimage:not(.disabled)').live('click', myclickevent);

$('#mydisablebutton').click( function () { $('#myimage').addClass('disabled'); });

Avec ce code, si vous cliquez sur #mydisablebutton, la classe désactivée sera ajoutée à l'élément #myimage. Cela fera en sorte que le sélecteur ne corresponde plus à l'élément et que l'événement ne soit déclenché que lorsque la classe 'désactivée' est supprimée, ce qui rend le sélecteur .live () valide à nouveau.

Cela présente d'autres avantages en ajoutant un style basé sur cette classe.

62
MacAnthony

Cela peut être fait en utilisant la fonction unbind.

$('#myimage').unbind('click');

Vous pouvez ajouter plusieurs gestionnaires d'événements au même objet et au même événement dans jQuery. Cela signifie que l'ajout d'un nouveau ne remplace pas les anciens.

Il existe plusieurs stratégies pour changer les gestionnaires d'événements, telles que les espaces de nom d'événements. Il y a quelques pages à ce sujet dans les documents en ligne.

Regardez cette question (c'est comme ça que j'ai appris le délier). Il existe une description utile de ces stratégies dans les réponses.

Comment lire les fonctions de rappel survolées dans jquery

37
Mnebuerquo

Si vous souhaitez répondre à un événement ne seule fois, la syntaxe suivante devrait être très utile:

 $('.myLink').bind('click', function() {
   //do some things

   $(this).unbind('click', arguments.callee); //unbind *just this handler*
 });

Avec arguments.callee, nous pouvons nous assurer que le gestionnaire de fonctions anonymes spécifique est supprimé et disposer ainsi d’un gestionnaire de temps unique pour un événement donné. J'espère que cela aide les autres.

34
ghayes

peut-être que la méthode unbind fonctionnera pour vous

$("#myimage").unbind("click");
31
John Boker

Je devais définir l'événement sur null en utilisant l'accessoire et l'attr. Je ne pouvais pas le faire avec l'un ou l'autre. Je ne pouvais pas non plus me mettre au travail. Je travaille sur un élément TD.

.prop("onclick", null).attr("onclick", null)
29
dwhittenburg

Vous pouvez ajouter le gestionnaire onclick en tant que balisage en ligne:

<input id="addreport" type="button" value="Add New Report" onclick="openAdd()" />

Si tel est le cas, jquery .off() ou .unbind() ne fonctionnera pas. Vous devez également ajouter le gestionnaire d'événements d'origine dans jQuery:

$("#addreport").on("click", "", function (e) {
   openAdd();
});

Ensuite, jquery a une référence au gestionnaire d'événements et peut le supprimer:

$("#addreport").off("click")

VoidKing le mentionne un peu plus haut dans un commentaire ci-dessus.

11
davaus

Si event est attaché de cette façon, et que la cible doit être non attachée:

$('#container').on('click','span',function(eo){
    alert(1);

    $(this).off(); //seams easy, but does not work

    $('#container').off('click','span'); //clears click event for every span

    $(this).on("click",function(){return false;}); //this works.

});​
11
user669677

Mise à jour pour 2014

En utilisant la dernière version de jQuery, vous pouvez maintenant dissocier tous les événements d'un espace-noms en faisant simplement $( "#foo" ).off( ".myNamespace" );

9
alexpls

Merci pour l'information. très utile je l'ai utilisé pour verrouiller l'interaction de la page en mode édition par un autre utilisateur. Je l'ai utilisé en conjonction avec ajaxComplete. Pas nécessairement le même comportement mais un peu similaire.

function userPageLock(){
    $("body").bind("ajaxComplete.lockpage", function(){
        $("body").unbind("ajaxComplete.lockpage");
        executePageLock();      
    });
};  

function executePageLock(){
    //do something
}
7
jquery_user

Le meilleur moyen de supprimer l’événement inline onclick est $(element).prop('onclick', null);

7
Shahrukh Azeem

Pour removeALLevent-handlers, voici ce qui a fonctionné pour moi:

Supprimer tous les gestionnaires d'événements signifie avoir le plain HTML structure sans tout le event handlers attaché à la element et son child nodes. Pour ce faire, jQuery's clone() a aidé.

var original, clone;
// element with id my-div and its child nodes have some event-handlers
original = $('#my-div');
clone = original.clone();
//
original.replaceWith(clone);

Avec cela, nous aurons la clone à la place de la original sans event-handlers.

Bonne chance...

5
Akash

Dans le cas où la méthode .on() était utilisée auparavant avec un sélecteur particulier, comme dans l'exemple suivant:

$('body').on('click', '.dynamicTarget', function () {
    // Code goes here
});

Les deux méthodes unbind() et .off() ne vont pas .

Cependant, la méthode . Undelegate () peut être utilisée pour supprimer complètement le gestionnaire de l'événement pour tous les éléments qui correspondent au sélecteur actuel:

$("body").undelegate(".dynamicTarget", "click")
5
Ilia Rostovtsev

Cela fonctionne aussi très bien. Simple et facile.voir http://jsfiddle.net/uZc8w/570/

$('#myimage').removeAttr("click");
3
Somnath Kharat

si vous définissez la onclick via html, vous devez removeAttr ($(this).removeAttr('onclick'))

si vous le définissez via jquery (comme après le premier clic dans mes exemples ci-dessus), vous devez alors unbind($(this).unbind('click'))

2
Ishan Liyanage

Si vous utilisez $(document).on() pour ajouter un écouteur à un élément créé dynamiquement, vous devrez peut-être utiliser ce qui suit pour le supprimer:

// add the listener
$(document).on('click','.element',function(){
    // stuff
});

// remove the listener
$(document).off("click", ".element");

2
ow3n

Toutes les approches décrites ne fonctionnaient pas pour moi car j'y ajoutais l'événement click avec on() au document où l'élément a été créé à l'exécution:

$(document).on("click", ".button", function() {
    doSomething();
});


Ma solution de contournement:

Comme je ne pouvais pas dissocier la classe ".button", j'ai simplement assigné une autre classe au bouton ayant les mêmes styles CSS. En faisant cela, le gestionnaire live/on-event a ignoré le clic:

// prevent another click on the button by assigning another class
$(".button").attr("class","buttonOff");

J'espère que ça t'as aidé.

1
Kai Noack

Je sais que cela arrive tard, mais pourquoi ne pas utiliser JS pour supprimer l'événement?

var myElement = document.getElementByID("your_ID");
myElement.onclick = null;

ou, si vous utilisez une fonction nommée en tant que gestionnaire d'événements:

function eh(event){...}
var myElement = document.getElementByID("your_ID");
myElement.addEventListener("click",eh); // add event handler
myElement.removeEventListener("click",eh); //remove it
1
Silviu Preda

J'espère que mon code ci-dessous explique tout. HTML:

(function($){

     $("#btn_add").on("click",function(){
       $("#btn_click").on("click",added_handler);
       alert("Added new handler to button 1");
     });

  
 
     $("#btn_remove").on("click",function(){
       $("#btn_click").off("click",added_handler);
       alert("Removed new handler to button 1");
     });

  
   function fixed_handler(){
    alert("Fixed handler");
  }
  
   function added_handler(){
    alert("new handler");
  }
  
  $("#btn_click").on("click",fixed_handler);
  $("#btn_fixed").on("click",fixed_handler);
  
  
})(jQuery);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="btn_click">Button 1</button>
  <button id="btn_add">Add Handler</button>
  <button id="btn_remove">Remove Handler</button>
  <button id="btn_fixed">Fixed Handler</button>
1
mysticmo