暂时禁止jQuery事件处理

有一种优雅的方式来暂时抑制jQuery事件吗? 我使用这样的代码:

$(element).unbind(event, function1).unbind(event, function2); // code for which the event is suppressed $(element).bind(event, function1).bind(event, function2); 

但我发现它有点笨拙,并且对很多事件来说都不是很容易扩展。 为什么我要暂时压制事件? 我使用BlockUI插件在Ajax访问期间阻止UI。 这是通过BlockUI提出的: $()。ajaxStart($。blockUI).ajaxStop($ .unblockUI)来完成的。

但是,一个Ajax访问是特殊的,所以我需要一个不同的消息。 ajaxStart和ajaxStop事件会干扰消息代码(不显示任何内容):

 function message(text, callback) { if (text == undefined) { $.unblockUI(); return; } // $().unbind('ajaxStop', $.unblockUI).unbind('ajaxStart', $.blockUI); $("#message_text").html(text); $.blockUI({message: $("#message")}); $("#message_ok").click(function() { // $().bind('ajaxStop', $.unblockUI).bind('ajaxStart', $.blockUI); $.unblockUI(); if (callback != undefined) callback(); }); } 

只有当我取消注释unbind()和bind()行时,它才有效。

我意识到这个问题已经过时了,但我在寻找同一个问题的答案时找到了它,并最终找到了一个在事件处理程序的简单应用程序中运行良好的不同解决方案。

 $(element).click(function(e) { e.preventDefault(); // Check for fired class if ($(this).hasClass('fired') == false) { // Add fired class to all instances of element $(element).addClass('fired'); // Do the rest of the function... // Remove fired class to 'reactivate' events $(element).removeClass('fired'); } } 

只需在事件代码触发时向您的’元素添加一个类,就可以防止由于另一个单击事件而执行更多代码。 因此,当您实际上没有阻止任何其他点击事件时,您将阻止生成的代码。 简单粗暴,忽略了对绑定和取消绑定的大量宣传使用,但是有效。

花了我这个脚本,我希望它有用:

           
test1 click mousemove
test2 click mousemove

我真的很喜欢Andres解决这个问题的方法,但看起来自从他提出了这个代码以来,jQuery事件模型已经改变了,所以在最近的jQuery版本中他的代码不起作用。 在这里它是现代化的。 在1.8.2中测试(轻微):

 $.event.freezeEvents = function(elem) { if (typeof($._funcFreeze)=="undefined") { $._funcFreeze = []; } if (typeof($._funcNull)=="undefined") { $._funcNull = function() {}; } // don't do events on text and comment nodes if ( elem.nodeType == 3 || elem.nodeType == 8 ) { return; } var events = $._data(elem, "events"); if (events) { $.each(events, function(type, definition) { $.each(definition, function(index, event) { if (event.handler != $._funcNull){ $._funcFreeze["events_freeze_" + event.guid] = event.handler; event.handler = $._funcNull; } }) }) } } $.event.unFreezeEvents = function(elem) { // don't do events on text and comment nodes if ( elem.nodeType == 3 || elem.nodeType == 8 ) return; var events = $._data(elem, "events"); if (events) { $.each(events, function(type, definition) { $.each(definition, function(index, event) { if (event.handler == $._funcNull){ event.handler = $._funcFreeze["events_freeze_" + event.guid]; } }) }) } } $.fn.freezeEvents = function() { return this.each(function(){ $.event.freezeEvents(this); }); }; $.fn.unFreezeEvents = function() { return this.each(function(){ $.event.unFreezeEvents(this); }); }; 

我没有在有两个事件的元素之外测试这个,但它适用于我。 希望这有助于某人。

最简单的方法是在绑定方法的开头添加一个检查,以确定该方法是否应该运行。 如果没有,只需从方法返回。

 var doThing = true; $("#foo").bind("click", function(e) { if(!doThing){return;} //do thing } function bar(){ //temp unbind click doThing = false; //do stuff... //rebind click doThing = true; } 

那么阻止页面,触发多个ajax请求(链接或其他)然后取消阻止页面的想法是什么?

如果是这种情况(并且我已经正确地理解了这个问题)那么你可以使用一个块计数器吗?

例如var blockcounter = 0;

 function block(){ if(blockcounter==0) {$.blockUI({message: "Hai", showOverlay:true});} blockcounter++; } function unblock(){ blockcounter--; if(blockcounter==0) {$.unblockUI();} } 

然后在你的代码中

 function dostuff(){ block(); ... do whatever ajax you need ... call unblock() in the success event of your ajax call } function dostuff2(){ block(); ... do some more ajax - this might take a bit longer to complete though ... call unblock() in the success event } dostuff(); dostuff2(); 

阻止应该只发生一次,你可以自由地在中间做任何事情。

我在网站上成功使用此方法,在阻止和解除阻塞之间发生了多个事件,并且不同的ajax事件可以在不同的时间完成。 如果将整批包装在命名空间中,您还可以避免乱丢全局变量的地方。

您可以简单地保存和恢复整个事件对象:

 var events=$._data(elem, 'events'); // save events $._data(elem, 'events', {}); // cancel all events // any code here will not fire events $._data(elem, 'events', events); // restore events 

这对我有用,但可能有未知的副作用……