jQuery – Como desabilitar temporariamente o ouvinte de events onclick após o evento ter sido triggersdo?

Como posso desativar temporariamente o ouvinte de events onclick, (jQuery preferido), após o evento ter sido triggersdo?

Exemplo:

Depois que o usuário clica no botão e triggers essa function abaixo, eu quero desabilitar o ouvinte onclick, portanto, não triggersndo o mesmo comando para a minha visualização do 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 }); } }); 

Muito obrigado,

Aldo

Existem muitas maneiras de fazer isso. Por exemplo:

 $(".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); }); } 

Também podemos usar a delegação de events para um código mais claro e melhor desempenho:

 $(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"); }); }); 

Se não precisarmos reativar o manipulador depois que ele for executado, poderemos usar o método .one() . Ele liga manipuladores que devem ser executados apenas uma vez. Veja os documentos do jQuery: http://api.jquery.com/one

Por quanto tempo você deseja desativar o ouvinte de evento de clique? Uma maneira é desvincular o ouvinte de events usando o jQuery’s unbind http://docs.jquery.com/Events/unbind .

Mas é uma prática recomendada não desvincular um evento apenas para reativá-lo mais tarde. Use um booleano em vez disso.

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

Editar: para estar seguro, você também deve se preocupar com as outras rotinas de conclusão do ajax (existem apenas três: success , error , complete , ver docs ) ou então active pode permanecer falso.

Por que não desativar o botão? Qualquer motivo específico que você deseja desativar este listner sozinho? BTB, do seu código, vejo que você está fazendo uma chamada de ajax. Então você quer especificamente bloquear o usuário até que a chamada volte? Se sim, você pode tentar o blockUI , um plugin jQuery

Eu configuraria uma variável global para acompanhar as solicitações do AJAX …

 var myApp = { ajax: null } 

E então tenha esse pouquinho de mágica para parar solicitações simultâneas …

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

Com essa abordagem, você não precisará voltar pelo código e modificar cada uma das chamadas do AJAX. (algo que eu chamo de solução “append”)

Eu usaria uma class, por exemplo, ‘ajax-running’. O evento click só será executado se o elemento clicado não tiver a class ‘ajax-running’. Assim que a chamada ajax terminar, você poderá remover a class ‘ajax-running’ para que ela possa ser clicada novamente.

 $(".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'); }); }; } }); 

Sugiro desativar o botão e reativá-lo nas rotinas de conclusão do Ajax (sucesso ou falha, lembre-se). Se você está preocupado com o fato de o navegador não respeitar a desativação do botão, é possível fazer isso com seu próprio sinalizador no botão (por exemplo, definir um atributo chamado data-disabled , usar o prefixo de data- como boa prática e ser compatível com HTML5 ). Mas, na verdade, ao se deparar com problemas com navegadores que não desabilitam o botão, eu provavelmente consideraria isso bom o suficiente.

Você poderia fazer a ação dentro do clique com base em um valor booleano. Quando clicado, altere o valor booleano e use setTimeout () para alterá-lo após alguns segundos. Isso limitaria efetivamente o usuário a clicar no botão apenas uma vez a cada poucos segundos.

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

Se você estiver postando via ajax, poderá desativar o botão ao clicar e ativá-lo após a conclusão do processo. Mas se você está postando de volta, você não pode simplesmente desativar o botão. Desativar o botão faz com que o evento de clique do lado do servidor não seja acionado. Então, basta esconder o botão ao clicar e mostrar uma mensagem amigável. A postagem sobre como desabilitar o botão asp.net no postback ajuda.

você também pode ocultar o botão (ou o div)

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

e você pode simplesmente chamar .show () se precisar exibi-lo novamente.

Além disso, dependendo do seu caso de uso, você deve considerar o uso de uma sobreposição de carregamento