web-dev-qa-db-fra.com

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énements 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

37
aldux

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(returnedData) {
        // ... do your stuff ...
        $this.removeData("executing");
    });
});

ou

$(".btnRemove").click(handler);

function handler() {
    var $this = $(this)
        .off("click", handler)
        .attr("src", "/url/to/ajax-loader.gif");
    $.get("/url/to/Django/view/to/remove/item/" + this.id, function(returnedData) {
        // ... 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(returnedData) {
        // ... 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

66
thorn̈

Pendant combien de temps souhaitez-vous désactiver l'écouteur d'événements Click? Une façon consiste à dissocier l'auditeur d'événements en utilisant unbindhttp://docs.jquery.com/Events/unbind de jQuery.

Mais il est préférable de ne pas dissocier un événement pour le relier plus tard. Utilisez plutôt un booléen.

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 également vous soucier des autres routines d'achèvement ajax (il n'y en a que trois: success, error, completevoir les documents ) sinon active pourrait rester faux.

19
RamboNo5

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. SO vous voulez spécifiquement bloquer l'utilisateur jusqu'à ce que l'appel revienne? Si oui, vous pouvez essayer blockUI , un plugin jQuery

5
ram

Je voudrais configurer une variable globale pour garder une trace de AJAX requêtes ...

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 AJAX. (Ce que j'appelle une solution "ajouter"))

3
Josh Stodola

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');
            });
        };
    }   
});
2
Mariano Cavallo

Vous pouvez effectuer l'action au sein du clic en fonction d'une valeur booléenne. Lorsque vous cliquez dessus, modifiez la valeur booléenne et utilisez setTimeout () pour la modifier à nouveau après quelques secondes. Cela limiterait efficacement l'utilisateur à ne cliquer sur le bouton qu'une fois toutes les quelques secondes.

var isEnabled = true;

$("a.clickMe").click(function(e){
  e.preventDefault();
  if (isEnabled == true) {
    isEnabled = false; // disable future clicks for now
    do_Something();
    setTimeout(function(){
      isEnabled = true;
    }, 3000); // restore functionality after 3 seconds
  }
});
2
Sampson
var ajaxAction = function() {
    var ele = $(this);
    ele.unbind("click", ajaxAction);
    ele.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) {
            });
        },
        complete: function() {
            ele.bind("click", ajaxAction);
        }
    });
}
$(".btnRemove").click(ajaxAction);
1
jitter

Si vous publiez via ajax, vous pouvez désactiver le bouton en un clic et l'activer une fois le processus terminé. Mais si vous publiez, vous ne pouvez pas simplement désactiver le bouton. La désactivation du bouton provoque le déclenchement de l'événement de clic côté serveur. Il suffit donc de masquer le bouton au clic et d'afficher un message convivial. Le post sur comment désactiver le bouton asp.net sur postback aide.

1
sangam

Je suggère de désactiver le bouton, puis de le réactiver dans vos routines d'achèvement Ajax (succès o échec, rappelez-vous). Si vous craignez que le navigateur ne respecte pas votre désactivation du bouton, vous pouvez sauvegarder cela avec votre propre indicateur sur le bouton (par exemple, définissez un attribut appelé data-disabled, en utilisant le data- préfixe comme bonne pratique et pour être compatible HTML5). Mais à moins de rencontrer des problèmes avec les navigateurs qui ne désactivent pas le bouton, je considérerais probablement que c'est assez bien.

1
T.J. Crowder

vous pouvez également masquer le bouton (ou le div contenant)

$(".btnRemove").click(function() {
   $(this).hide();
   // your code here...
})

et vous pouvez simplement appeler .show () si vous avez besoin de l'afficher à nouveau.

En fonction de votre cas d'utilisation, vous devriez également envisager d'utiliser une superposition de chargement

0
jules345