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

IT技术 javascript jquery ajax events onclick
2021-01-20 09:50:38

在触发事件后,如何暂时禁用 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                       
     });
   }
});

非常感谢,

奥尔多

6个回答

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

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

在这种情况下,您应该使用 .one() 方法绑定仅执行一次的处理程序。请参阅 jQuery 文档:docs.jquery.com/Events/one
2021-03-15 09:50:38
这个对我有用。我可以安全地解除绑定,因为一旦 do stuff 部分结束,图像按钮就会被破坏。
2021-03-19 09:50:38
@timaschew 是的,但问题不是关于禁用 <a> 元素,而是禁用点击处理程序。在这种情况下, <a> 上的 disabled 属性作为一个标志来排除我们的点击处理程序。
2021-03-21 09:50:38
是的,我不知道 one() 方法。这将以更优雅的方式完成!谢谢。
2021-04-03 09:50:38
.on("click", ".btmRemove:not([disabled])", 如果您更喜欢设置 disabled 属性而不是使用类,则是另一种选择。
2021-04-03 09:50:38

您要禁用单击事件侦听器多长时间?一种方法是使用 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 看文档),或者active威力逗留假。

无论如何,这不会总是回来吗......?
2021-03-27 09:50:38
这是如何完成工作的,active 只不过是在开始时读取的布尔值
2021-03-28 09:50:38
active保持 false 直到 ajax 请求成功完成。在这段时间内,点击处理程序立即返回开始,所以它基本上没有执行。
2021-04-03 09:50:38
@TaylorA.Leach 既然你提到了它,我认为 if 语句中的第一个检查应该是if (!active). 我会更新答案。
2021-04-04 09:50:38
我喜欢返回 false 的简单性......我不知道这是否比以某种方式停止传播更好的做法,但在我的情况下它更容易并且有效=)
2021-04-08 09:50:38

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

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

从 jQuery 1.9 开始,jQuery 全局 Ajax 事件的所有处理程序,包括使用 .ajaxStart() 方法添加的处理程序,都必须附加到文档中。
2021-04-01 09:50:38

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