2009-12-17 87 views
35

如何在事件被触发后暂时禁用onclick事件侦听器(jQuery首选)?jQuery - 如何在事件触发后暂时禁用onclick事件侦听器?

例子:

上的按钮和火灾低于这个功能,我想禁用的onclick监听用户点击之后,因此不发射相同的命令,以我的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      
    }); 
    } 
}); 

非常感谢,

阿尔

+0

如何暂时?在您想再次接受点击事件之前发生了什么? – 2009-12-17 13:42:23

+9

(PS。不允许GET请求执行状态更改。) – bobince 2009-12-17 13:47:20

+2

@bobince:哦,如果我们都遵守了这个简单的规则,那不是很好... @OP:更多关于bob的讨论内容(惊恐地turgid散文)在这里:http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.1.2 – 2009-12-17 13:51:46

回答

64

有很多方法可以做到这一点。例如:

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

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

我们也可以使用事件代表团更清晰的代码和更好的性能:

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

如果我们不需要重新启用处理程序在它被执行后,我们可以使用.one()方法。它绑定只能执行一次的处理程序。查看jQuery文档:http://api.jquery.com/one

+0

这一个为我工作。我可以安全地取消绑定它,因为一旦这个东西部分结束,图像按钮就会被销毁。 – aldux 2009-12-18 18:18:26

+3

在这种情况下,您应该使用.one()方法来绑定只能执行一次的处理程序。查看jQuery文档:http://docs.jquery.com/Events/one – thorn 2009-12-20 22:02:00

+0

是的,我不知道one()方法。这将以更优雅的方式做到!谢谢。 – aldux 2010-05-12 21:05:56

5

为什么不能禁用按钮?要单独禁用此听者任何具体的原因是什么? BTB,从您的代码中,我看到您正在进行ajax调用。所以你特意要阻止用户,直到电话回来?如果是的话,你可以尝试blockUI,一个jQuery插件

1

我建议禁用按钮,然后重新启用它在你的Ajax完成例程(成功失败,记不清了)。如果您担心浏览器不尊重您的禁用按钮,您可以在按钮上使用自己的标志(例如,设置一个名为data-disabled的属性,使用data-前缀作为良好做法并与HTML5兼容)。但是,除非实际遇到浏览器未禁用按钮的问题,否则我可能会考虑到这一点。

18

要停用点击事件侦听器多长时间?一种方法是使用jQuery的unbindhttp://docs.jquery.com/Events/unbind解绑定事件监听器。

但最好不要解除绑定事件以后重新绑定。改为使用布尔值。

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

编辑:是安全的,你也应该关心其他AJAX完成例程(只有三个:successerrorcompletesee docs),或者active可能会留下假的。

+0

这是如何完成这项工作的,active只不过是在开始时读取的一个布尔值 – TStamper 2009-12-17 13:56:18

+2

'active'保持为false直到ajax请求成功结束。在那段时间内点击处理程序立即返回,因此它基本上不会执行。 – RamboNo5 2009-12-17 14:03:33

+0

did not catch that inside ..谢谢 – TStamper 2009-12-17 14:12:16

1

您可以根据布尔值在点击内进行操作。点击时,更改布尔值并使用setTimeout()在几秒钟后将其更改回来。这将有效地限制用户每隔几秒仅点击一次按钮。

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

我真的很喜欢这种方法,非常简单,开销很小。谢谢乔纳森! – 2012-07-04 16:17:58

1
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); 
+0

我实际上会补充这一点。在这些例子中,比起所有其他的箍环都更加清楚地命名它,并且在内部解除绑定/重新绑定。 – 2012-07-17 16:14:04

3

我会设置一个全局变量来跟踪AJAX请求......

var myApp = { 
    ajax: null 
} 

再有魔力这一点停止的同时请求......

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

使用这种方法,您不必回头查看代码并修改每一个AJAX调用。 (我称之为“追加”解决方案)

+0

从jQuery 1.9开始,[jQuery全局Ajax事件](http://api.jquery.com/category/ajax/global-ajax-event-handlers/)的所有处理程序,包括与.ajaxStart( )方法,必须附加到文档中。 – ooXei1sh 2015-12-19 15:04:49

2

我会使用一个类,例如'ajax-running'。点击事件只会在被点击的元素没有'ajax-running'类时执行。只要您ajax调用完成,您可以删除'ajax-running'类,以便它可以再次单击。

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

如果您通过ajax发布,您可以禁用单击按钮并在过程完成后启用它。但是,如果你回来发布,你不能只是禁用按钮。禁用该按钮会导致服务器端点击事件不会触发。所以只需点击按钮并显示用户友好的信息即可。 how to disable asp.net button on postback上的帖子有帮助。

0

,你也可以只隐藏按钮(或者内含div)

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

,你可以直接调用.show()如果你需要再次显示。

还取决于你的使用情况,你应该考虑使用加载覆盖,而不是