2009-04-20 309 views
8

在與阿賈克斯事件的網頁,我要禁用所有動作,直到Ajax調用返回(以防止問題的雙重提交等)Javascript:如何暫時禁用頁面上的所有操作?

我通過預先return false;到當前的onclick事件嘗試過這種當「鎖定」該頁面,並在「解鎖」頁面時稍後刪除。但是,這些操作在「解鎖」後不再活動 - 您無法觸發它們。

爲什麼這不起作用?見下面的示例頁面。任何其他想法來實現我的目標?

示例代碼:
鏈接和按鈕都顯示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> 

謝謝你們對自己的想法和解答。

現在我明白了,我已經混了絃樂和功能,這顯然不能工作;(

我應該明確表示,我們使用它創建事件處理某些Web FW和標籤庫(特立尼達和多巴哥) (和Ajax)代碼,因此我無法直接編輯或使用同步Ajax等。

此外,Ajax只是一個應該執行此代碼的場景,目的是防止用戶雙擊提交page/action,這對非Ajax頁面也很重要,在這裏你可以點擊一個按鈕。我知道這不是很安全,它只是爲了避免導航的「方便」錯誤頁面(我們當然有服務器端的保護)。

所以,可能會嘗試div覆蓋。

再次感謝,
克里斯托弗。

回答

9

如何當Ajax調用然後開始遞減,當它完成建立一個全局變量

actions_disabled = 0 

增量。所有的「動作」處理程序然後可以開始

if (actions_disabled) return false; 

比調試自修改代碼更簡單!

另外,鎖定你的控制,你可以設置:

control.disabled="disabled" 

這將有花白出來,使它明顯的是,他們無法提交用戶的獎金。要解鎖,只需設置:

control.disabled="" 

新思路基於評論(不能引用註釋中的代碼,它似乎...):

你總是可以只掛附加屬性關閉JavaScript對象:

要鎖定,您可以:

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

要解鎖,您可以:

control.onclick = control.onclick_old 
2

我曾經通過創建一個覆蓋我想要禁用的區域的DIV來實現此目標,其設置的z-index高於頁面上的任何其他元素,然後將其opacity設置爲0。默認情況下,這個DIV被display: none隱藏,所以它不會干涉任何事情。但是,當我想要禁用該區域時,我只是將其display設置爲block

史蒂夫

+0

感謝您的回答,但這實際上並不是客戶想要的...... ;-( 頁面應該顯示不變(所有按鈕,字段等都可見),但只能防止用戶觸發另一個操作或第二次採取同樣的行動。 – ami 2009-04-20 09:11:33

+0

這就是建議。頁面不會有任何可見的變化。你甚至不需要改變不透明度 - 只需保持div空,並在'none'和'block'之間切換顯示屬性。 – ozan 2009-04-20 09:19:13

+0

哦,是的,我明白了。應該更仔細地閱讀這個;) 將嘗試這種方法... – ami 2009-04-20 09:27:55

1

AJAX。異步。只要使HTTP請求同步即可。問題解決了。

1

您的代碼存在的問題是由於未與JavaScript中的類型進行交涉而導致的。

當你說:

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

這樣做是強迫EL [I] .onclick(這是一個功能)爲一個字符串,然後它加到字符串 '返回false;'。然後,當你重新分配它像這樣:這是以前的功能

el[i].onclick = newEvent; 

的onclick現在是一個字符串。

然後嘗試通過採取子從字符串復活舊功能:

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

這是很好的,除了newEvent仍然是一個字符串!因此,當您將其重新分配給onclick時,您將分配原始函數的字符串表示,而不是函數本身。

您可以使用eval來評估字符串並返回函數,但請不要這樣做。正如其他評論者所建議的,有很多更好的方法可以做到這一點。

我也會質疑爲什麼你希望使用AJAX,如果你不想允許異步請求。

0

使用div覆蓋不會阻止用戶選項卡進入您的頁面。通常這是可以的,因爲大多數用戶不會在任何地方通過頁面選項卡。

如果您在頁面上使用任何鍵盤快捷鍵,它們仍然可用,因此需要單獨處理。

另外,我假定點擊一個可以有焦點的元素(例如,一個<a>標籤),然後按回車,仍然會導致一個雙重提交。

相關問題