jQuery 이벤트 처리를 일시적으로 억제합니다
-
05-07-2019 - |
문제
jQuery 이벤트를 일시적으로 억제하는 우아한 방법이 있습니까? 나는 다음과 같은 코드를 사용합니다.
$(element).unbind(event, function1).unbind(event, function2);
// code for which the event is suppressed
$(element).bind(event, function1).bind(event, function2);
그러나 나는 그것이 약간 서투르고 많은 사건에 대해서는 확장 할 수 없다는 것을 알았습니다. 이벤트를 일시적으로 억제하고 싶은 이유는 무엇입니까? Ajax 액세스 중에 Blockui 플러그인을 사용하여 UI를 차단합니다. 이것은 다음과 같습니다. $ (). ajaxstart ($. blockui) .ajaxstop ($. Unblockui) Blockui가 제안한대로.
그러나 하나의 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');
}
}
이벤트의 코드가 발사되는 동안 '요소에 클래스를 추가하면 다른 클릭 이벤트의 결과로 추가 코드가 실행되는 것을 방지 할 수 있습니다. 따라서 실제로 다른 클릭 이벤트를 방해하지는 않지만 결과 코드가 실행되는 것을 방지합니다. 단순하고 조잡한 것은 묶여 있고 바인딩되지 않은 설교의 사용을 무시하지만 효과가 있습니다.
다른 팁
이 스크립트를 마치고 유용하기를 바랍니다.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript">
$(function(){
//ini plugin
jQuery.event.freezeEvents = function(elem) {
if (typeof(jQuery._funcFreeze)=="undefined")
jQuery._funcFreeze = [];
if (typeof(jQuery._funcNull)=="undefined")
jQuery._funcNull = function(){ };
// don't do events on text and comment nodes
if ( elem.nodeType == 3 || elem.nodeType == 8 )
return;
var events = jQuery.data(elem, "events"), ret, index;
if ( events ) {
for ( var type in events )
{
if ( events[type] ) {
var namespaces = type.split(".");
type = namespaces.shift();
var namespace = RegExp("(^|\\.)" + namespaces.slice().sort().join(".*\\.") + "(\\.|$)");
for ( var handle in events[type] )
if ( namespace.test(events[type][handle].type) ){
if (events[type][handle] != jQuery._funcNull){
jQuery._funcFreeze["events_freeze_" + handle] = events[type][handle];
events[type][handle] = jQuery._funcNull;
}
}
}
}
}
}
jQuery.event.unFreezeEvents = function(elem) {
// don't do events on text and comment nodes
if ( elem.nodeType == 3 || elem.nodeType == 8 )
return;
var events = jQuery.data(elem, "events"), ret, index;
if ( events ) {
for ( var type in events )
{
if ( events[type] ) {
var namespaces = type.split(".");
type = namespaces.shift();
for ( var handle in events[type] )
if (events[type][handle]==jQuery._funcNull)
events[type][handle] = jQuery._funcFreeze["events_freeze_" + handle];
}
}
}
}
jQuery.fn.freezeEvents = function() {
return this.each(function(){
jQuery.event.freezeEvents(this);
});
};
jQuery.fn.unFreezeEvents = function() {
return this.each(function(){
jQuery.event.unFreezeEvents(this);
});
};
//end plugin
jQuery("#test1").ajaxStart(function test1(){
jQuery("#result").append('test1 ajaxStop<br>');
});
jQuery("#test1").ajaxStop(function test2(){
jQuery("#result").append('test1 click<br>');
});
jQuery("#test1").bind("click", function test3(){
jQuery("#result").append('test1 click<br>');
});
jQuery("#test2").bind("click", function test5(){
jQuery("#result").append('test2 click<br>');
});
jQuery("#freez").click(function(){
jQuery("#test1").freezeEvents();
jQuery("#test2").freezeEvents();
});
jQuery("#unfreez").click(function(){
jQuery("#test1").unFreezeEvents();
jQuery("#test2").unFreezeEvents();
});
});
</script>
</head>
<body>
<button id="freez">freez</button>
<button id="unfreez">un freez</button>
<br />
<div id="test1">test1 click mousemove</div>
<div id="test2">test2 click mousemove</div>
<br />
<div id="result"></div>
</body>
</html>
나는이 문제에 대한 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;
}
전체 이벤트 개체를 단순히 저장하고 복원 할 수 있습니다.
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
이것은 나를 위해 효과가 있었지만 부작용이 알려지지 않았을 수도 있습니다 ...
그렇다면 페이지를 차단하고 여러 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 이벤트가 다양한 시간 내에 완료 될 수있는 웹 사이트에서 성공적으로 사용합니다. 네임 스페이스로 전체를 감싸면 글로벌 VARS와 함께 장소를 쓰지 않도록 할 수도 있습니다.