La meilleure façon de supprimer un gestionnaire d'événements dans jQuery?

1053

J'en ai un input type="image". Cela agit comme les notes de cellule dans Microsoft Excel. Si quelqu'un entre un nombre dans la zone de texte avec laquelle il input-imageest associé, je configure un gestionnaire d'événements pour le input-image. Ensuite, lorsque l'utilisateur clique sur image, il obtient une petite fenêtre contextuelle 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 input-imagegestionnaire d'événements de. J'ai essayé ce qui suit, mais en vain.

$('#myimage').click(function { return false; });
Randy L
la source

Réponses:

1626

jQuery ≥ 1,7

Avec jQuery 1.7 et ultérieur, l'API d'événement a été mise à jour, .bind()/ .unbind()sont toujours disponibles pour la compatibilité descendante, mais la méthode préférée utilise les fonctions on () / off () . Ce qui suit 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 renvoyés.

Comme les gens l'ont dit, vous pouvez utiliser la dissociation 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 l'espace de noms des événements:

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

et pour supprimer uniquement votre événement:

$('#myimage').unbind('click.mynamespace');
samjudson
la source
6
Existe-t-il un moyen de tester si cela unbind()fonctionne? Je l'ai ajouté et les deux événements se déclenchent toujours.
David Yell
19
Eh bien, si les deux événements se déclenchent, cela ne fonctionne évidemment pas. Il faudrait donner plus d'informations pour obtenir une réponse correcte. Essayez de poser une question distincte.
samjudson
13
Ancienne réponse - comme les informations d'espace de noms incluses - mais j'oublie; on / off renvoie-t-il l'objet jQ? Si c'est le cas, une réponse plus complète serait peut-être de $('#myimage').off('click').on('click',function(){...})
connecter
3
Oui, ils le font, donc oui, si vous vouliez effacer tous les autres événements de clic, puis ajouter le vôtre, vous pourriez faire l'appel chaîné ci-dessus.
samjudson
L'utilisation .unbind()m'a aidé dans une situation où je basculais un tas de cases à cocher, mais relâché, je rajoutais le .click()gestionnaire à plusieurs reprises, provoquant le blocage de l'application.
TecBrat
63

Ce n'était pas disponible lorsque cette question a été répondue, 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'); });

Ce qui se passera avec ce code, c'est que lorsque vous cliquez sur #mydisablebutton, il ajoutera la classe désactivée à l'élément #myimage. Cela fera en sorte que le sélecteur ne correspondra plus à l'élément et que l'événement ne sera pas déclenché jusqu'à ce que la classe «désactivé» soit supprimée, ce qui rend le sélecteur .live () à nouveau valide.

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

MacAnthony
la source
3
Belle façon d'utiliser live(), jamais pensé à l'utiliser de cette façon auparavant ... Mis à part la commodité du codage, est-ce plus rapide ou offre-t-il d'autres avantages à l'utilisation de bind / unbind?
chakrit
2
Si vous ajoutez / supprimez des éléments, il existe des avantages de performances indéniables par rapport à bind, car la liaison avec live n'est effectuée qu'une seule fois. jQuery semble s'orienter vers des événements plus vivants et délégués plutôt que de se lier à des éléments spécifiques.
MacAnthony
3
Pour désactiver en direct, vous pouvez utiliser die ()
Moons
9
"Depuis jQuery 1.7, la méthode .live () est obsolète. Utilisez .on () pour attacher des gestionnaires d'événements. Les utilisateurs d'anciennes versions de jQuery devraient utiliser .delegate () de préférence à .live ()." api.jquery.com/live
Lucas Pottersky
12
Ah, jQuery capricieux, un jour vous apportez 300 rep à un gars, le lendemain c'est obsolète.
MrBoJangles
37

Si vous souhaitez répondre à un événement une 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*
 });

En utilisant arguments.callee , nous pouvons nous assurer que le gestionnaire de fonction anonyme spécifique est supprimé, et donc avoir un gestionnaire de temps unique pour un événement donné. J'espère que cela aide les autres.

ghayes
la source
2
Absolument, bien que parfois vous souhaitiez peut-être avoir une certaine logique sur le moment où le gestionnaire doit être non lié (par exemple, ne dissociez pas à moins qu'ils aient déposé une zone de texte en premier).
ghayes
5
arguments.callee est déprécié en mode strict!
zloctb
37

Cela peut être fait en utilisant la fonction de dissociation.

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

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

Il existe plusieurs stratégies pour modifier les gestionnaires d'événements, tels que les espaces de noms 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 à délier). Il y a une description utile de ces stratégies dans les réponses.

Comment lire les fonctions de rappel hover liées dans jquery

Mnebuerquo
la source
32

peut-être que la méthode de déliaison fonctionnera pour vous

$("#myimage").unbind("click");
John Boker
la source
30

J'ai dû mettre l'événement à zéro 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 faire fonctionner .unbind. Je travaille sur un élément TD.

.prop("onclick", null).attr("onclick", null)
dwhittenburg
la source
1
J'ai voté pour cela parce que j'essaie de délier un onblur pendant environ 30 minutes. '.unbind' n'a pas fonctionné, '.prop' n'a pas fonctionné, '.attr' n'a pas fonctionné, mais cette astuce avec .prop et .attr ensemble a fait l'affaire. impair. J'utilise Chrome avec jquery 1.7.2
Jeremy
Pareil ici! j'ai essayé de supprimer l'événement click de la simple balise <a>! Merci pour cela. Dans mon cas, .prop ("onclick", null) était suffisant.
Jan Lobau
pareil ici. unbind and off n'a pas fonctionné pour moi sur FF avec jq 1.7.2 et .prop ("onclick", null) était également suffisant dans mon cas
bryanallott
4
Je pense que la raison pour laquelle les méthodes ci-dessus n'ont pas fonctionné pour vous est la façon dont vous l'avez configurée. Si vous avez écrit le gestionnaire d'événements dans le DOM, alors oui, la suppression de cet attribut est nécessaire pour effacer le gestionnaire d'événements, cependant, je pense que la plupart des gens (y compris moi-même) souhaitent garder ces choses (javascrip, gestionnaires d'événements, etc.) hors du DOM, donc quand nous voulons configurer un gestionnaire d'événements, nous utilisons quelque chose comme $("#elementId").click(function(){//Event execution code goes here});pour qu'il ne soit pas du tout dans la page html. Pour effacer que nous devons réellement utiliser .unbind(), ou le préféré.off()
VoidKing
Voici un exemple de quelqu'un qui vient de passer une heure à découvrir que les propriétés ajoutées via jQuery ne s'affichent pas sur le panneau des éléments de Chrome. J'ai essayé unbindet offça n'a pas résolu le problème. Merci beaucoup!
Renan
13

Si l'événement est attaché de cette façon et que la cible doit être détaché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.

});​

la source
11

Vous pouvez ajouter le onclickgestionnaire en tant que balisage en ligne:

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

Si c'est le cas, le 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, le jquery a une référence au gestionnaire d'événements et peut le supprimer:

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

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

davaus
la source
9

Mise à jour pour 2014

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

alexpls
la source
8

La meilleure façon de supprimer un événement onclick en ligne est $(element).prop('onclick', null);

Shahrukh Azeem
la source
8

Pour remove TOUS event-handlers , c'est ce qui a fonctionné pour moi:

Supprimer tous les gestionnaires d'événements signifie avoir la plaine HTML structuresans tous les event handlersattachés à la elementet à la sienne child nodes. Pour ce faire, jQuery's clone()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 le cloneà la place du originalsans event-handlers.

Bonne chance...

Akash
la source
7

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 quelque peu similaire.

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

function executePageLock(){
    //do something
}
jquery_user
la source
5

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

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

Les deux unbind()et les .off()méthodes ne sont pas aller au travail.

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")
Ilia Rostovtsev
la source
1
J'ai fait défiler la page entière pendant que je cherchais cette solution, j'ai travaillé comme un charme.
Abhishek Pandey
4

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");
ow3n
la source
2

si vous définissez la onclickvia, htmlvous devezremoveAttr ($(this).removeAttr('onclick'))

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

Ishan Liyanage
la source
2

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

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

ou, si vous utilisez une fonction nommée comme 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
Silviu Preda
la source
Bonne suggestion, je préfère utiliser le javascript natif lorsqu'il est disponible
Michiel
1

Toutes les approches décrites n'ont pas fonctionné pour moi car j'ajoutais l'événement click avec on() au document où l'élément a été créé au moment de l'exécution:

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


Ma solution:

Comme je ne pouvais pas dissocier la classe ".button", je viens d'assigner une autre classe au bouton qui avait les mêmes styles CSS. Ce faisant, le gestionnaire live / on-event a finalement ignoré le clic:

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

J'espère que cela pourra aider.

Kai Noack
la source
1

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>

mysticmo
la source
1
pourquoi passez-vous })(jQuery);dans l'IIFE alors qu'il est déjà accessible à l'échelle mondiale?
Bryan P
2
Bonne question Bryan. Cette méthode a été entrée dans mon gène en raison de la pratique. - Il peut y avoir une possibilité pour le plugin non jquery d'avoir la variable $, donc je ne peux pas utiliser $ directement. - L'utilisation fréquente du mot "jQuery" dans un fichier de script js peut augmenter la taille en octets du fichier, où jQuery est une chaîne de 6 octets. Par conséquent, je préfère utiliser "$" ou toute variable d'un seul octet.
mysticmo
0

Supprimez simplement cela du bouton:

$('.classname').click(function(){
$( ".classname" ).remove();
});
Mitra
la source