jQuery的 – 如何在事件被解雇后暂时禁用onclick事件监听器?

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

例:

当用户点击button并在下面触发这个function后,我想禁用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 }); } }); 

非常感谢,

阿尔

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

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

您要多久禁用点击事件侦听器? 一种方法是使用jQuery的unbind http://docs.jquery.com/Events/unbind解除事件监听器的;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完成例程(只有三个: successerrorcomplete 看文档 ),否则active可能会保持错误。

为什么不禁用button?任何具体的原因,你想单独禁用此列表器? BTB,从你的代码,我看到你正在做一个Ajax调用。 所以你特别想阻止用户,直到电话回来? 如果是的话,你可以尝试blockUI ,一个jQuery插件

我会设置一个全局variables来跟踪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调用。 (我称之为“追加”解决scheme)

我会用一个类,例如'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'); }); }; } }); 

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

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

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

如果您通过ajax发布,您可以禁用单击button,并在过程完成后启用它。 但是,如果你回来发布,你不能只是禁用button。 禁用该button会导致服务器端单击事件不会触发。 所以只需点击button隐藏button,并显示用户友好的信息。 关于如何禁用回发asp.netbutton的post有帮助。

你也可以隐藏button(或包含div)

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

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

也取决于你的使用情况,你应该考虑使用加载覆盖