jQuery-Comment puis-je désactiver temporairement l'écouteur d'event onclick après que l'event a été tiré?

Comment puis-je désactiver temporairement l'écouteur onclick event, (jQuery preferred), après que l'événement a été déclenché?

Exemple:

après que l'utilisateur clique sur le bouton et déclenche cette fonction ci-dessous, je veux désactiver l'écouteur onclick, donc ne pas lancer la même commande à 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
demandé sur T.J. Crowder 2009-12-17 16:39:12

10 réponses

Il y a beaucoup de façons de le faire. 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énement pour un code plus clair et une meilleure performance:

$(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 qu'il a été exécuté, alors nous pouvons utiliser la .one() méthode. Il lie les manipulateurs qui ne doivent être exécutés qu'une seule fois. Voir jQuery docs:http://api.jquery.com/one

65
répondu thorn 2015-08-26 14:29:54

pendant combien de temps Voulez-vous désactiver l'écouteur de clics? Une façon est de déballer l'écouteur d'événements en utilisant jquery unbindhttp://docs.jquery.com/Events/unbind.

mais c'est une bonne pratique de ne pas décrocher un événement pour le reprendre plus tard. Utilisez 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,completevoir docs), ou alors active pourrait rester faux.

19
répondu RamboNo5 2018-07-01 08:32:27

pourquoi ne pas désactiver le bouton ?Une raison spécifique pour laquelle vous voulez désactiver ce listner seul ? BTB, d'après votre code, je vois que vous faites un appel ajax. SI vous souhaitez bloquer l'utilisateur jusqu'à ce que l'appel revient ? Si oui, vous pouvez essayer blockUI, Un plugin jQuery

5
répondu ram 2009-12-17 13:43:07

j'installerais une variable globale pour garder la trace des requêtes AJAX...

var myApp = {
  ajax: null
}

et puis avoir 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 à revenir en arrière à travers votre code et modifier chacun de vos appels AJAX. (ce que j'appelle un "annexer" de la solution)

3
répondu Josh Stodola 2009-12-17 14:23:14

j'utiliserais une classe par exemple 'ajax-running'. L'événement click aurait ne sera exécutée que si l'élément cliqué n'a pas le 'ajax' classe. Dès que vous avez terminé votre appel ajax, vous pouvez supprimer la classe' ajax-running ' pour qu'elle puisse être cliquée à 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
répondu Mariano Cavallo 2009-12-17 15:35:27

je suggère de désactiver le bouton, puis de le réactiver dans vos routines D'achèvement Ajax (succès ou échec, rappelez-vous). Si vous craignez que le navigateur ne respecte pas votre désactivation du bouton, vous pouvez appuyer sur votre propre drapeau sur le bouton (par exemple, définir 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 assez bon.

1
répondu T.J. Crowder 2009-12-17 13:46:23

Vous pouvez faire l'action dans le clic basé sur une valeur booléenne. Quand il est cliqué, changer la valeur booléenne et uset setTimeout() pour changer de nouveau après quelques secondes. Cela limiterait effectivement l'utilisateur à cliquer le bouton une seule 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
  }
});
1
répondu Sampson 2009-12-17 14:07:15
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
répondu jitter 2009-12-17 14:12:20

si vous postez via ajax, vous pouvez désactiver le bouton sur le clic et l'activer après le processus terminé. Mais si vous postez en arrière, vous ne pouvez pas juste désactiver le bouton. Si le bouton est désactivé, l'événement de clic latéral du serveur ne se déclenche pas. Donc, il suffit de cacher le bouton sur le clic et afficher le message convivial. Le post sur comment désactiver asp.net bouton de publication aide.

1
répondu sangam 2011-09-29 08:53:35

Vous pouvez aussi simplement cacher le bouton (ou la div contenant)

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

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

en fonction de votre cas d'utilisation, vous devriez également envisager l'utilisation d'une superposition de chargement à la place de

0
répondu jules345 2015-12-30 12:13:59