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; });

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');

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.


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.


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


32

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

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

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)

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.

});​

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.


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" );


8

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


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...


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
}

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")

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");


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'))


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

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.


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>


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();
});
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.