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
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
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 unbind
http://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
,complete
voir docs), ou alors active
pourrait rester faux.
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
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)
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');
});
};
}
});
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.
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
}
});
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);
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.
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