2009-04-20 2 views
8

, 나는 자바 스크립트 : 페이지의 모든 동작을 일시적으로 사용 중지하는 방법은 무엇입니까? 아약스 이벤트와 페이지에서

내가 현재의 onclick 이벤트에 return false;를 앞에 붙이는이 시도 (등을 제출 번 문제를 방지하기 위해) Ajax 호출이 반환 될 때까지 모든 작업을 비활성화 할 때 "잠금" 페이지를 제거하고 나중에 페이지를 "잠금 해제"할 때이를 제거하십시오. 그러나 액션은 "잠금 해제"된 후에 더 이상 활성화되지 않습니다. 단지 트리거 할 수 없습니다.

왜 작동하지 않습니까? 아래 예제 페이지를 참조하십시오. 내 목표를 달성하기위한 다른 아이디어?

예제 코드 :
링크와 버튼 모두 JS 경고를 표시합니다. 자물쇠를 누르면 이벤트 처리기의 잠금을 해제하는 것은 이전과 동일하지만 작동하지 않습니다 ...?!?
코드는 결국 트리니다 드와 함께 작동하도록되어 있지만 외부에서도 작동해야합니다. 여러분의 아이디어와 답변을

<html><head><title>Test</title> 

<script type="text/javascript"> 
function lockPage() 
{ 
    document.body.style.cursor = 'wait'; 
    lockElements(document.getElementsByTagName("a")); 
    lockElements(document.getElementsByTagName("input")); 

    if (typeof TrPage != "undefined") 
    { 
    TrPage.getInstance().getRequestQueue().addStateChangeListener(unlockPage); 
    } 
} 

function lockElements(el) 
{ 
    for (var i=0; i<el.length; i++) 
    { 
    el[i].style.cursor = 'wait'; 
    if (el[i].onclick) 
    { 
     var newEvent = 'return false;' + el[i].onclick; 
     alert(el[i].onclick + "\n\nlock -->\n\n" + newEvent); 
     el[i].onclick = newEvent; 
    } 
    } 
} 

function unlockPage(state) 
{ 
    if (typeof TrRequestQueue == "undefined" || state == TrRequestQueue.STATE_READY) 
    { 
    //alert("unlocking for state: " + state); 
    document.body.style.cursor = 'auto'; 
    unlockElements(document.getElementsByTagName("a")); 
    unlockElements(document.getElementsByTagName("input")); 
    } 
} 

function unlockElements(el) 
{ 
    for (var i=0; i<el.length; i++) 
    { 
    el[i].style.cursor = 'auto'; 
    if (el[i].onclick && el[i].onclick.search(/^return false;/)==0) 
    { 
     var newEvent = el[i].onclick.substring(13); 
     alert(el[i].onclick + "\n\nunlock -->\n\n" + newEvent); 
     el[i].onclick = newEvent; 
    } 
    } 
} 
</script> 

<style type="text/css"> 
</style> 
</head> 

<body> 

<h1>Page lock/unlock test</h1> 

<p>Use these actions to lock or unlock active elements on the page: 
<a href="javascript:lockPage()">lock</a>, 
<a href="javascript:unlockPage()">unlock</a>.</p> 

<p>And now some elements:</p> 

<a onclick="alert('This is the action!');return false;" href="#">link action</a> &nbsp; 
<input type="button" value="button action" onclick="alert('This is another action!')"/> 
</body> 
</html> 

고마워.

지금 나는 분명히 작동하지 않을 수 있습니다 문자열과 기능을 혼합 한 것을 볼 (

나는 우리가 이벤트 처리를 만드는 일부 웹 FW와 태그 라이브러리 (트리니다드)을 사용하는 것이 분명히해야

(및 Ajax) 코드를 사용하므로 직접 편집하거나 동기식 Ajax 등을 사용할 수 없습니다.

또한 Ajax는이 코드를 실행해야하는 시나리오 중 하나입니다. page/action은 버튼에 doulbe-click을 할 수있는 non-Ajax 페이지와도 관련이 있습니다. 이건 정말 안전하지 않고 네비게이션을 얻지 못하게하는 "편의상"일뿐입니다. 오류 페이지 너무 자주 (우리는 서버 측 보호 기능을 가지고 있습니다.)

그래서 div 오버레이를 시도 할 것입니다.

다시 한 번 감사드립니다.
Christoph.

답변

9

어떻게이 완료되면 AJAX 호출이 다음 감소를 시작할 때

actions_disabled = 0 

증가를 글로벌 VAR를 설정하는 방법에 대한. 모든 "액션"핸들러는 다음으로 시작할 수 있습니다

if (actions_disabled) return false; 

자체 수정 코드를 디버깅하는 것보다 훨씬 간단합니다!또한

, 당신은 설정할 수 있습니다 당신의 컨트롤을 잠 그려면 : 그들은 제출할 수없는 사용자에게이 분명하고, 그들을 어지는의 보너스를해야합니다

control.disabled="disabled" 

. 잠금을 해제하려면 설정 :

control.disabled="" 

(이 나타납니다 ... 주석 코드를 인용 할 수 없음) 의견을 기반으로하는 새로운 IDEA :

당신은 언제나 놀 수 추가 자바 스크립트 객체를 속성 :

당신이 수, 잠글 :

control.onclick_old = control.onclick 
control.onclick = "return false;" 

잠금을 해제하려면 수 :

,471,
+0

고마워,하지만 불행히도 작업 코드는 트리니다 드 프레임 워크에 의해 생성되며 나는 그것을 직접 변경할 수 없습니다. 그래서 JS를 사용하여 이벤트 핸들러 코드를 변경해야합니다. – ami

+0

작업을 "줄 바꿈"할 수 있습니까? function thingo_wrap (e) { if (actions_disabled) false를 반환합니다. return original_thing () 위의 대체 제안 사항을 참조하십시오. – NickZoic

+0

좋은 생각 ... 직접 할 수는 없지만 일부 JS를 사용하여 작업을 수정하십시오. 내 원래의 솔루션이 작동하지 않는 이유는 함수와 문자열을 섞어 놓은 것 같습니다. 맞습니까? 나는 그것을 시도 할 것이다. 또는지도를 사용하여 원래 작업을 저장하고 나중에 복원 할 수도 있습니다. – ami

2

장애가있는 영역을 포함하는 DIV를 작성하여 페이지의 다른 요소보다 높은 z-index을 설정 한 다음 opacity0으로 설정하여이 목표를 달성했습니다. 기본적으로이 DIV는 display: none으로 숨겨져 아무 것도 방해하지 않습니다. 그러나이 영역을 사용하지 않으려면 displayblock으로 설정합니다.

스티브

+0

답변 주셔서 감사합니다. 실제로 고객이 원하는 것이 아닙니다. ;-( 페이지가 변경되지 않고 표시되어야하지만 (버튼, 필드 등은 모두 표시되어야 함) 사용자가 다른 작업을 트리거하는 것을 방지해야합니다. 또는 두 번째 동일한 작업. – ami

+0

그것이 제안되고 있습니다. 페이지에 눈에 보이는 변화는 없습니다. 불투명도를 변경할 필요가 없습니다. div를 비워두고 'none'과 'block'사이의 표시 속성을 전환하십시오. – ozan

+0

아, 그래요.)이 접근법을 시도 할 것입니다 ... – ami

1

AJAX. 비동기. HTTP 요청을 동 기화하십시오. 문제 해결됨.

+0

글쎄, 당신 말이 맞아,하지만 ... 한편, 코드 의이 부분은 우리의 웹 FW에 의해 생성되며 그것에 직접 제어 할 수 없습니다. 반면에, 주된 목적은 Ajax 호출뿐만 아니라 모든 페이지에서 동일한 메커니즘이 사용되도록 이중 제출 (기존 서버 측 탐지에 대한 추가 계층)을 방지하는 것입니다. 방금 Ajax를 예로 들었습니다. – ami

1

코드 문제는 자바 스크립트에서 유형이 그립에 오지 않은 결과입니다.

당신이 말할 때 :

var newEvent = 'return false;' + el[i].onclick 

무엇이하는 일은 [I] .onclick (함수 인) 문자열로, 다음 문자열로 연결합니다 엘 강요는 'false를 반환;'. 그런 다음 다시 할당 할 때 :

el[i].onclick = newEvent; 

이전에 함수였던 onclick이 이제 문자열입니다.

은 그럼 당신은 문자열을 복용하여 문자열에서 기존의 기능을 부활하려고 : newEvent 제외하고 괜찮

var newEvent = el[i].onclick.substring(13); 

여전히 문자열입니다! 그래서 다시 onclick에 할당하면 함수 자체가 아니라 원래 함수의 문자열 표현을 할당하게됩니다.

eval을 사용하여 문자열을 평가하고 함수를 반환 할 수는 있지만 그렇게하지 마십시오. 다른 의견 작성자들에 의해 제안 된 바와 같이이를 수행하는 여러 가지 좋은 방법이 있습니다.

비동기 요청을 허용하지 않으려는 이유는 AJAX를 전혀 사용하지 않는 이유입니다.

0

div 오버레이를 사용한다고해서 사용자가 페이지에 탭하지 못하게하는 것은 아닙니다. 대부분의 사용자가 페이지를 통해 탭하지 않으므로 일반적으로 정상입니다.

페이지에서 키보드 단축키를 사용하더라도 여전히 사용할 수 있으므로 별도의 처리가 필요합니다.

내가 포커스를 가질 수있는 요소 (예 : <a> 태그)를 클릭하고 Enter 키를 누르면 여전히 두 번 제출됩니다.

관련 문제