[英]Javascript: How to temporarily disable all actions on the page?
在帶有 Ajax 事件的頁面上,我想禁用所有操作,直到 Ajax 調用返回(以防止重復提交等問題)
我通過預先設置return false;
嘗試這個return false;
“鎖定”頁面時的當前 onclick 事件,稍后在“解鎖”頁面時將其刪除。 但是,這些操作在“解鎖”后不再處於活動狀態——您只是無法觸發它們。
為什么這不起作用? 請參閱下面的示例頁面。 還有其他想法可以實現我的目標嗎?
示例代碼:
鏈接和按鈕都顯示 JS 警報; 當按下鎖定時,則解鎖事件處理程序與之前相同,但不起作用......?!?
該代碼旨在最終與 Trinidad 一起使用,但也應該在外部使用。
<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>
<input type="button" value="button action" onclick="alert('This is another action!')"/>
</body>
</html>
謝謝你們的想法和答案。
現在我看到我把字符串和函數搞混了,這顯然是行不通的;(
我應該明確指出我們使用了一些創建事件處理(和 Ajax)代碼的 Web FW 和標記庫(Trinidad),因此我無法直接編輯它們或使用同步 Ajax 等。
而且,Ajax 只是應該執行此代碼的一種場景。 它的目的是防止用戶重復提交頁面/操作,這也與非 Ajax 頁面相關,您可以在其中雙擊按鈕。 我知道這並不是真的安全,它只是為了避免過於頻繁地獲取導航錯誤頁面(當然,我們有服務器端保護)是一種“方便”的東西。
所以,可能會嘗試 div 覆蓋。
再次感謝,
克里斯托夫。
如何設置一個全局變量
actions_disabled = 0
AJAX 調用開始時增加,結束時減少。 然后,您所有的“動作”處理程序都可以從
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
我曾經通過創建一個覆蓋我想要禁用的區域的 DIV 來實現這個目標,將其z-index
設置為高於頁面上任何其他元素,然后將其opacity
設置為0
。 默認情況下,這個 DIV 被display: none
隱藏,這樣它就不會干擾任何東西。 但是,當我想要禁用該區域時,我只需將其display
設置為block
。
史蒂夫
將 lockPage() 放在 activete() 函數的頂部,將 unlockPage() 放在 deactivate() 的底部。
activate: function() {
function lockPage()
{
lockElements(document.getElementsByTagName("a"));
lockElements(document.getElementsByTagName("input"));
lockElements(document.getElementsByTagName("button"));
};
function lockElements(el)
{
for (var i=0; i<el.length; i++)
{
el[i].style.pointerEvents="none";
}
};
lockPage();
// ...
},
deactivate: function() {
// ...
function unlockPage() {
unlockElements(document.getElementsByTagName("a"));
unlockElements(document.getElementsByTagName("input"));
unlockElements(document.getElementsByTagName("button"));
};
function unlockElements(el)
{
for (var i=0; i<el.length; i++)
{
el[i].style.pointerEvents="auto";
}
};
unlockPage();
},
阿賈克斯。 異步。 只需使 HTTP 請求同步即可。 問題解決了。
您的代碼的問題是因為沒有掌握 javascript 中的類型。
當你說:
var newEvent = 'return false;' + el[i].onclick
它的作用是將 el[i].onclick(這是一個函數)強制轉換為一個字符串,然后將其連接到字符串 'return false;'。 然后當你重新分配它時:
el[i].onclick = newEvent;
以前是一個函數的 onclick 現在是一個字符串。
然后,您嘗試通過獲取子字符串來從字符串中恢復舊函數:
var newEvent = el[i].onclick.substring(13);
這很好,除了 newEvent 仍然是一個字符串! 因此,當您再次將其分配回 onclick 時,您分配的是原始函數的字符串表示形式,而不是函數本身。
您可以使用 eval 來評估字符串並返回函數,但請不要這樣做。 正如其他評論者所建議的那樣,有許多更好的方法可以做到這一點。
如果您不想允許異步請求,我還會質疑為什么您希望使用 AJAX。
使用 div 覆蓋不會阻止用戶通過 Tab 鍵進入您的頁面。 通常這是可以的,因為大多數用戶無論如何都不會瀏覽頁面。
如果您在頁面上使用任何鍵盤快捷鍵,它們仍然可用,因此需要對它們進行單獨處理。
另外,我假設單擊可以具有焦點的元素(例如<a>
標簽),然后按 Enter 鍵,仍然會導致雙重提交。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.