如何在 jQuery 中暂时禁用单击处理程序?

假设我有下面这样的东西来捕捉按钮的点击事件:

$("#button_id").click(function() {
//disable click event
//do something
//re-enable click event
}

如何暂时禁用按钮的点击事件,直到原始点击处理结束?我基本上让 div 在按钮被点击后消失,但是如果用户快速点击按钮几次,它会在 div 有机会消失之前处理所有这些点击。我想“去除”按钮,以便只有第一次点击注册之前,div 消失。

108435 次浏览
$("#button_id").click(function() {
if($(this).data('dont')==1) return;
$(this).data('dont',1);
//do something
$(this).data('dont',0);
}

请记住,$. data ()仅适用于具有 ID 的项目。

如果 # Button _ id 意味着一个标准的 HTML 按钮(比如提交按钮) ,那么可以使用“禁用”属性使该按钮对浏览器不起作用。

$("#button_id").click(function() {
$('#button_id').attr('disabled', 'true');


//do something


$('#button_id').removeAttr('disabled');
});

但是,您可能需要注意的是这些事情发生的顺序。如果您使用的是 jquery hide 命令,那么您可能需要包含“ $(’# Button _ id’)”。作为回调的一部分,以便在隐藏完成之前不会发生。

使用回调函数的例子:

$("#button_id").click(function() {
$('#button_id').attr('disabled', 'true');
$('#myDiv').hide(function() { $('#button_id').removeAttr('disabled'); });
});

相对于人工状态变量解,这是一种更为惯用的替代方法:

$("#button_id").one('click', DoSomething);


function DoSomething() {
// do something.


$("#button_id").one('click', DoSomething);
}

一个 只执行一次(直到再次附加)。更多信息在这里: < a href = “ http://docs.jquery.com/Events/One”rel = “ norefrer”> http://docs.jquery.com/events/One

$("#button_id").click(function() {
$('#button_id').attr('disabled', 'true');
$('#myDiv').hide(function() { $('#button_id').removeAttr('disabled'); });
});

不要用 .attr()来做残疾人,用 .prop()比较好。

这个例子管用。


HTML 代码:

  <div class="wrapper">
<div class="mask">Something</div>
</div>

JQuery:

    var fade = function(){
$(".mask").fadeToggle(500,function(){
$(this).parent().on("click",function(){
$(this).off("click");
fade();
});
});
};


$(".wrapper").on("click",function(){
$(this).off("click");
fade();
});

此代码将显示加载到按钮标签,并设置按钮禁用状态,然后在处理后,重新启用并返回原来的按钮文本:

$(function () {


$(".btn-Loading").each(function (idx, elm) {
$(elm).click(function () {
//do processing
if ($(".input-validation-error").length > 0)
return;
$(this).attr("label", $(this).text()).text("loading ....");
$(this).delay(1000).animate({ disabled: true }, 1000, function () {
//original event call
$.when($(elm).delay(1000).one("click")).done(function () {
$(this).animate({ disabled: false }, 1000, function () {
$(this).text($(this).attr("label"));
})
});
//processing finalized
});
});
});
// and fire it after definition
}
);

我注意到这个帖子是旧的,但它出现在谷歌和这种解决方案从来没有提供顶部,所以我决定张贴无论如何。

您只需禁用游标事件,稍后通过 css 再次启用它们。所有主流浏览器都支持它,在某些情况下可能会很有用。

$("#button_id").click(function() {


$("#button_id").css("pointer-events", "none");
//do something
$("#button_id").css("pointer-events", "auto");
}

你可以像我之前告诉你的那些人一样,用一个表情:

使用按钮元素的. data 来共享一个 look 变量(或者只是一个全局变量)

if ($('#buttonId').data('locked') == 1)
return
$('#buttonId').data('locked') = 1;
// Do your thing
$('#buttonId').data('locked') = 0;

B)关闭鼠标信号

$("#buttonId").css("pointer-events", "none");
// Do your thing
$("#buttonId").css("pointer-events", "auto");

如果它是一个 HTML 按钮,你可以禁用它(输入[ type = mit ]或按钮)

$("#buttonId").attr("disabled", "true");
// Do your thing
$("#buttonId").attr("disabled", "false");

但是注意其他线程! 我失败了很多次,因为我的动画(淡入或淡出)需要一秒钟。 例如,fadeIn/fadeOut 支持将回调函数作为第二个参数。 如果没有其他方法,只能使用 setTimeout(callback, delay)

你好, 托马斯

您可以使用 .off解除处理程序的绑定,但是有一个警告; 如果您正在这样做,只是防止处理程序在运行时再次被触发,那么您需要推迟重新绑定处理程序。

例如,考虑下面这段代码,它使用5秒钟的热休眠来模拟从处理程序内部执行的同步和计算代价高昂的操作(比如重度 DOM 操作) :

<button id="foo">Click Me!</div>
<script>
function waitForFiveSeconds() {
var startTime = new Date();
while (new Date() - startTime < 5000) {}
}
$('#foo').click(function handler() {
// BAD CODE, DON'T COPY AND PASTE ME!
$('#foo').off('click');
console.log('Hello, World!');
waitForFiveSeconds();
$('#foo').click(handler);
});
</script>

没用的。正如您在 这个 JSFiddle中所看到的,如果您在处理程序已经执行时单击按钮,那么一旦第一次执行结束,处理程序将执行第二次。更重要的是,至少在 Chrome 和 Firefox 中,即使你不使用 jQuery,而是使用 addEventListenerremoveEventListener来添加和删除处理程序,这也是正确的。浏览器在第一次单击后执行处理程序,解除绑定并重新绑定处理程序,而 那么处理第二次单击并检查是否有要执行的单击处理程序。

为了解决这个问题,您需要延迟使用 setTimeout重新绑定处理程序,以便在第一个处理程序执行时发生的单击将被处理 之前,您将重新连接处理程序。

<button id="foo">Click Me!</div>
<script>
function waitForFiveSeconds() {
var startTime = new Date();
while (new Date() - startTime < 5000) {}
}
$('#foo').click(function handler() {
$('#foo').off('click');
console.log('Hello, World!');
waitForFiveSeconds();


// Defer rebinding the handler, so that any clicks that happened while
// it was unbound get processed first.
setTimeout(function () {
$('#foo').click(handler);
}, 0);
});
</script>

您可以在 这个修改过的 JSFiddle上看到这种情况。

当然,如果您在处理程序中所做的事情已经是异步的,那么这是不必要的,因为您已经将控制权交给了浏览器,并让它在重新绑定处理程序之前刷新所有的单击事件。例如,这样的代码在没有 setTimeout调用的情况下也能正常工作:

<button id="foo">Save Stuff</div>
<script>
$('#foo').click(function handler() {
$('#foo').off('click');
$.post( "/some_api/save_stuff", function() {
$('#foo').click(handler);
});
});
</script>

尝试使用 .one()

var button = $("#button"),
result = $("#result"),
buttonHandler = function buttonHandler(e) {
result.html("processing...");
$(this).fadeOut(1000, function() {
// do stuff
setTimeout(function() {
// reset `click` event at `button`
button.fadeIn({
duration: 500,
start: function() {
result.html("done at " + $.now());
}
}).one("click", buttonHandler);


}, 5000)
})
};


button.one("click", buttonHandler);
#button {
width: 50px;
height: 50px;
background: olive;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<div id="result"></div>
<div id="button">click</div>

最好使用当前事件,不要在全局处理程序中保存处理程序。 我得到当前元素事件,然后解除绑定,然后再绑定。 作为联络人。

var element =  $("#elemid")[0];
var tempHandler = jQuery._data(element)["events"]["click"][0].handler;
$("#elemid").unbind("click");


// do the job that click not suppose to listen;
$("#elemid").bind("click" , tempHandler );

所有处理人

var element =  $("#elemid")[0];
var clickHandlerList = jQuery._data(element)["events"]["click"];
var handlerList = [];
for(var i  = 0 ; i <  clickHandlerList .length ; i++) {
handlerList .push(clickHandlerList [i].handler);
}
$("#elemid").unbind("click");
// do the job that click not suppose to listen;
for(var i  = 0 ; i <  handlerList.length ; i++) {
// return back all handler to element.
$("#elemid").bind("click" , handlerList[i]);
}

我只是在等待函数完成时试图显示加载旋转器时遇到了这个问题。因为我将微调器添加到 HTML 中,所以每次单击按钮时,微调器都会被复制,如果你不反对在全局范围内定义一个变量,那么这对我来说很有效。

    var hasCardButtonBeenClicked = '';
$(".js-mela-card-button").on("click", function(){
if(!hasCardButtonBeenClicked){
hasCardButtonBeenClicked = true;
$(this).append('<i class="fa fa-circle-o-notch fa-spin" style="margin-left: 3px; font-size: 15px;" aria-hidden="true"></i>');
}
});

注意,我所做的只是声明一个变量,只要它的值是 无效,点击之后的操作就会发生,然后将变量值设置为“ true”(它可以是任何值,只要它不是空的) ,进一步禁用按钮,直到浏览器刷新或变量设置为 null。

回顾过去,将 hasCardButtonBeenClick 变量从“ false”开始设置,然后根据需要在“ true”和“ false”之间切换,可能会更有意义。