2015-11-03 160 views
2

我的問題很簡單:我必須在一個已有5年曆史的Web應用程序上工作,這些應用程序具有繁重的表單和多個按鈕,並且鏈接到頁面上的任何地方。而且我們遇到了麻煩,因爲我們的許多用戶雙擊按鈕和鏈接,通常以實際的雙重提交形式結束。防止雙擊導致HTML表單中的雙重提交

我知道大多數解決方案通常都是針對這種問題的peopole,比如說:「用於頁面上的任何按鈕,使其在第一次點擊後被禁用= true」。有些人還建議使用dblclick事件,忽略只有在短時間內發生兩個點擊事件時才拋出它 - 這意味着一旦觸發事件已經太晚了,因爲已經發生了兩次點擊。與preventDefault()方法一樣,該方法不能解決問題。

但是,至於禁用點擊策略,我不能重構應用程序的每一個頁面的代碼,以將onclick處理程序放在按鈕和鏈接上。另外,他們中的大多數已經有onclick處理程序附加,這意味着我將無法搜索和替換或類似的東西。而且我也不想在每個頁面加載時發出一個jQuery請求,這會在頁面的每個按鈕和鏈接上添加一個新的點擊事件處理程序。這會花費CPU資源,而且無論如何效率都不高,因爲有些按鈕會觸發彈出窗口而不是提交表單,而且這些按鈕必須可以多次點擊,還有其他類似的例子。

我在尋找的是一種簡單而通用的方式來告訴Web瀏覽器「當雙擊頁面上的任何地方,忽略第二次點擊」。我真的不明白爲什麼不可能這樣做。最有可能的原因是,當你發現自己處於這種狀況時,你已經遠離良好實踐,但這不是我的錯,我有一個問題需要解決。

回答

2

我終於找到了一個相當簡單的方法來解決沒人告訴我的問題(太簡單了?)。解決方案是使用將佔據所有窗口的不可見層,但默認情況下是禁用的。你可以聲明這樣說:

<div id="prevent_dbclick" style="z-index: 1300; border: 0 none; top: 0px; left: 0px; margin: 0px; padding: 0px; width: 100%; height: 100%; opacity: 0; position: fixed; display: none;">500</div> 

現在,你也需要這樣的JavaScript函數:

function disableDbClick(){ 
    jQuery(window).click(function(){ 
     var prevDbDiv = jQuery("#prevent_dbclick"); 
     prevDbDiv.show(); 
     setTimeout(function(){ 
      prevDbDiv.hide(); 
     }, prevDbDiv.html());  
    }); 
} 
window.onload = disableDbClick; 

請注意,我用的jQuery爲了簡化,但如果您的項目不使用jQuery,你可以輕鬆地工作它周圍。

現在只需在頁面加載後調用函數。它的工作方式非常簡單:只要在頁面上某處點擊,不可見圖層就會在頁面上超過500毫秒,然後消失,並且間隔中的任何點擊事件都會觸擊圖層而不是按鈕或鏈接,從而有效地防止雙擊雙擊提交。一旦延遲到期,人們可以自由地再次點擊任何地方。

選擇了500毫秒的延遲,因爲它是Windows用來區分連續兩次點擊的雙擊的延遲時間。我沒有在JavaScript代碼中對它進行硬編碼,因爲我希望能夠通過應用程序的屬性對其進行更改。

希望這會有所幫助。

+0

用例的好處在於,您無法正確重構遺留代碼。但副作用是,你真的阻止任何雙擊,所以萬一用戶真的需要執行一次,這是不可能的。另外,爲什麼不把時間存儲在數據集中,而不是存儲在innerHTML中(這是暫時可見的)? – ghybs

+0

AFAIK數據集API與HTML5一起出現。我的遺留應用程序仍然堅持HTML4。關於您希望允許雙擊的情況,我不會在這些頁面中使用該技巧,並手動禁用其他按鈕,但這可能是我們需要它的頁面的0.1%。此外,我認爲應該可以重塑圖層以部分覆蓋窗口,或者以其他方式思考,而不是將其應用於窗口元素,將其應用於頁面的一部分。任何我想在答案中儘可能簡單並且不提供人們可能不需要的東西 – Aldian

+0

其他可能性,因爲該圖層的z-索引爲1300,所以對於需要雙倍大小的控件使用更大的z-索引點擊工作。 – Aldian