39 votes

jQuery - Comment puis-je désactiver temporairement l'écouteur d'événements onclick après le déclenchement de l'événement?

Comment puis-je désactiver temporairement l'écouteur d'événement onclick, (jQuery préféré), après le déclenchement de l'événement?

Exemple:

Après que l'utilisateur a cliqué sur le bouton et déclenché cette fonction ci-dessous, je veux désactiver l'écouteur onclick, donc ne pas tirer la même commande sur ma vue django.

 $(".btnRemove").click(function(){
   $(this).attr("src", "/url/to/ajax-loader.gif");
   $.ajax({
        type: "GET",
        url: "/url/to/django/view/to/remove/item/" + this.id,
        dataType: "json",
        success: function(returned_data){
            $.each(returned_data, function(i, item){
              // do stuff                       
     });
   }
});
 

Merci beaucoup,

Aldo

66voto

thorn Points 2808

Il existe de nombreuses façons de procéder. Par exemple:

 $(".btnRemove").click(function() {
    var $this = $(this);
    if ($this.data("executing")) return;
    $this.data("executing", true).attr("src", "/url/to/ajax-loader.gif");
    $.get("/url/to/django/view/to/remove/item/" + this.id, function(returned_data) {
        // ... do your stuff ...
        $this.removeData("executing");
    });
});
 

ou

 $(".btnRemove").click(function() {
    var handler = arguments.callee;
    var $this = $(this).off("click", handler).attr("src", "/url/to/ajax-loader.gif");
    $.get("/url/to/django/view/to/remove/item/" + this.id, function(returned_data) {
        // ... do your stuff ...
        $this.click(handler);
    });
});
 

Nous pouvons également utiliser la délégation d'événements pour un code plus clair et de meilleures performances:

 $(document).on("click", ".btnRemove:not(.unclickable)", function() {
    var $this = $(this).addClass("unclickable").attr("src", "/url/to/ajax-loader.gif");
    $.get("/url/to/django/view/to/remove/item/" + this.id, function(returned_data) {
        // ... do your stuff ...
        $this.removeClass("unclickable");
    });
});
 

Si nous n'avons pas besoin de réactiver le gestionnaire après son exécution, nous pouvons utiliser la méthode .one() . Il lie les gestionnaires qui ne doivent être exécutés qu'une seule fois. Voir les documents jQuery: http://api.jquery.com/one

19voto

RamboNo5 Points 1154

pour combien de temps voulez-vous désactiver le clic de l'écouteur d'événement? une façon est de séparer l'écouteur d'événement à l'aide de jQuery unbind http://docs.jquery.com/Events/unbind. mais c'est mieux de ne pas séparer un événement seulement pour relier plus tard. utiliser un booléen à la place.

var active = true;
$(".btnRemove").click(function(){
   if(!active){
       return;
   }
   active = false;
   $(this).attr("src", "/url/to/ajax-loader.gif");
   $.ajax({
        type: "GET",
        url: "/url/to/django/view/to/remove/item/" + this.id,
        dataType: "json",
        success: function(returned_data){
        active = true; // activate it again !
        $.each(returned_data, function(i, item){
              // do stuff                       
     });
   }
});

edit: pour être sûr, vous devriez aussi vous soucier de l'ajax d'autres routines de fin (il y en a que trois: success, error, complete voir docs) ou active pourrait rester faux.

5voto

ram Points 4605

pourquoi ne pas désactiver le bouton? Une raison particulière pour laquelle vous souhaitez désactiver ce listeur seul? BTB, à partir de votre code, je vois que vous faites un appel ajax. DONC vous voulez spécifiquement bloquer l'utilisateur jusqu'à ce que l'appel revienne? Si oui, vous pouvez essayer blockUI , un plugin jQuery

3voto

Josh Stodola Points 42410

Je configurerais une variable globale pour garder une trace des requêtes AJAX ...

 var myApp = {
  ajax: null
}
 

Et puis ayez ce petit peu de magie pour arrêter les requêtes simultanées ...

 // Fired when an AJAX request begins
$.ajaxStart(function() { myApp.ajax = 1 });

// Fired when an AJAX request completes
$.ajaxComplete(function() { myApp.ajax = null });

// Fired before an AJAX request begins
$.ajaxSend(function(e, xhr, opt) {
  if(myApp.ajax != null) {
    alert("A request is currently processing. Please wait.");
    xhr.abort();
  }
});
 

Avec cette approche, vous ne devriez pas avoir à parcourir votre code et à modifier chacun de vos appels AJAX. (quelque chose que j'appelle une solution "ajouter")

2voto

iKindred Points 554

J'utiliserais une classe par exemple 'ajax-running'. L'événement click ne serait exécuté que si l'élément cliqué n'a pas la classe 'ajax-running'. Dès que votre appel ajax est terminé, vous pouvez supprimer la classe «ajax-running» afin de pouvoir la cliquer à nouveau.

 $(".btnRemove").click(function(){
    var $button			= $(this);
    var is_ajaxRunning 	= $button.hasClass('ajax-running');
    if( !is_ajaxRunning ){
    	$.ajax({
    		...
    		success: function(returned_data) {
    			...
    			$button.removeClass('ajax-running');
    		});
    	};
    }	
});
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X