如何暂时禁用jQuery中的点击处理程序?
说我有类似以下的东西来捕获一个button的点击事件:
$("#button_id").click(function() { //disable click event //do something //re-enable click event }
如何暂时禁用button的点击事件,直到原始点击处理结束? 点击button后我基本上已经消失了,但是如果用户多次点击button,它会在div有机会消失之前处理所有这些点击。 我想“消除”button,以便只有第一次点击获得登记之前div div消失。
我注意到这个post是旧的,但它似乎在谷歌顶部,这种解决scheme从来没有提供,所以我决定发布它。
您可以禁用游标事件,稍后再通过css启用它们。 它在所有主stream浏览器上都支持,在某些情况下可能会有用。
$("#button_id").click(function() { $("#button_id").css("pointer-events", "none"); //do something $("#button_id").css("pointer-events", "auto"); }
这是人工状态variables解决scheme的一个更习惯的select:
$("#button_id").one('click', DoSomething); function DoSomething() { // do something. $("#button_id").one('click', DoSomething); }
一个只会执行一次(直到再次连接)。 更多信息在这里: http : //docs.jquery.com/Events/one
$("#button_id").click(function() { if($(this).data('dont')==1) return; $(this).data('dont',1); //do something $(this).data('dont',0); }
记住$ .data()只适用于带有ID的项目。
你可以用.off
解除你的处理程序,但是有一个警告。 如果你这样做只是防止处理程序在已经运行时被再次触发,你需要推迟重新处理处理程序。
例如,考虑这个代码,它使用5秒的热hibernate来模拟处理程序内同步和计算成本高昂的事情(比如重型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中试用它,如果你在处理器已经执行的时候点击button,处理器将在第一次执行完成后再执行一次。 更重要的是,至less在Chrome和Firefox中,即使不使用jQuery,也可以使用addEventListener
和removeEventListener
来添加和删除处理程序。 浏览器在第一次单击之后执行处理程序,解除绑定和重新绑定处理程序, 然后处理第二次单击,并检查是否有要执行的单击处理程序。
为了解决这个问题,你需要推迟使用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中看到这个动作。
当然,如果你在你的处理程序中所做的事情已经是asynchronous的,那么这是不必要的,因为你已经在控制浏览器,让它刷新所有的点击事件,然后重新绑定你的处理程序。 例如,像这样的代码将正常工作,没有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>
如果#button_id意味着一个标准的HTMLbutton(如提交button),您可以使用“禁用”属性使button对浏览器不活动。
$("#button_id").click(function() { $('#button_id').attr('disabled', 'true'); //do something $('#button_id').removeAttr('disabled'); });
但是,您可能需要小心的是这些事情发生的顺序。 如果你正在使用jquery hide命令,你可能需要包含“$('#button_id')。removeAttr('disabled');” 作为回叫的一部分,以使其在隐藏完成之前不发生。
使用callback函数的例子:
$("#button_id").click(function() { $('#button_id').attr('disabled', 'true'); $('#myDiv').hide(function() { $('#button_id').removeAttr('disabled'); }); });
你可以像其他人那样做,然后用我的眼神告诉你:
A.)使用button元素的.data来共享一个外观variables(或一个公正的全局variables)
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");
C.)如果它是一个HTMLbutton,您可以禁用它(input[type = submit]或button)
$("#buttonId").attr("disabled", "true"); // Do your thing $("#buttonId").attr("disabled", "false");
但要小心其他线程! 我失败了很多次,因为我的animation(淡入淡出)花了一秒钟。 例如fadeIn / fadeOut支持一个callback函数作为第二个参数。 如果没有其他的方法只是使用setTimeout(callback, delay)
。
问候,托马斯
尝试使用.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>
这个例子工作。
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(); });
$("#button_id").click(function() { $('#button_id').attr('disabled', 'true'); $('#myDiv').hide(function() { $('#button_id').removeAttr('disabled'); }); });
不要使用.attr()
去做残疾人,使用.prop()
,那会更好。
这个代码会在button标签上显示加载,并且将button设置为禁用状态,然后在处理之后,重新启用并返回原来的button文本:
$(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 } );
一个简单的解决scheme是评论onclick属性中的代码:
要禁用onClick:
var code = $('#mybutton').attr("onclick"); btn.attr("onclick", '/*' + code + '*/');
要启用onClick:
var code = $('#mybutton').attr("onclick"); code = code.replace(/\*\//gi, " "); code = code.replace(/\/\*/gi, " "); $('#mybutton').attr("onclick", code);