jQuery - 如何在事件触发后暂时禁用onclick事件侦听器?

时间:2009-12-17 13:39:13

标签: javascript jquery ajax events onclick

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

示例:

用户点击按钮并在下面触发此功能后,我想禁用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                       
     });
   }
});

非常感谢,

阿尔

10 个答案:

答案 0 :(得分:66)

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

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

答案 1 :(得分:19)

您想要禁用click事件侦听器多长时间?一种方法是使用jQuery的unbind http://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完成例程(只有三个:successerrorcomplete {{ 3}})或者active可能保持错误。

答案 2 :(得分:5)

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

答案 3 :(得分: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调用。 (我称之为“附加”解决方案)

答案 4 :(得分:2)

您可以根据布尔值在单击中执行操作。单击它时,更改布尔值并使用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
  }
});

答案 5 :(得分:2)

我会使用一个类,例如'ajax-running'。只有当被点击的元素没有'ajax-running'类时,才会执行click事件。一旦你的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');
            });
        };
    }   
});

答案 6 :(得分:1)

我建议禁用该按钮,然后在Ajax完成例程中重新启用它(成功失败,请记住)。如果您担心浏览器不尊重您的禁用按钮,您可以在按钮上使用您自己的标记(例如,设置名为data-disabled的属性),使用data-前缀作为良好做法并与HTML5兼容)。但是,除非实际上遇到浏览器没有禁用按钮的问题,我可能会认为这很好。

答案 7 :(得分: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);

答案 8 :(得分:1)

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

答案 9 :(得分:0)

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

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

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

另外,根据您的使用情况,您应该考虑使用加载覆盖