定理:
您所遇到的問題是,能夠有效地運行該腳本排隊點擊。只要在事件處理程序正在運行的瀏覽器窗口沒有響應,但則仍會記錄點擊,並儘快處理程序進行處理,
所以,你要做的就是
在handler1:
只有在此之後,點擊纔會被處理(即使您在事件處理期間點擊了它)。因爲那時button2被啓用,handler2也會運行。
證明:
用一塊HTML的,你可以檢查:
<button id="test1" onclick="window.test1();">Test1</button>
<button id="test2" onclick="window.test2();">Test2</button>
和文字:
window.test1 = function()
{
document.getElementById('test2').disabled = true;
for (var i=0; i<1000000000; i++);
document.getElementById('test2').disabled = false;
alert('Test1 done'); // Notice: Alert after enabling button 2.
}
window.test2 = function()
{
document.getElementById('test1').disabled = true;
for (var i=0; i<1000000000; i++);
alert('Test2 done'); // Notice: Alert before re-enabling button 1.
document.getElementById('test1').disabled = false;
}
兩個按鈕,他們每個人將執行一個類似的,耗時的腳本。如果您在循環運行時單擊按鈕1並快速按下按鈕2,則會注意到這兩個處理程序都被調用,但您也會看到另一個按鈕在循環期間沒有(視覺)禁用,因爲要禁用的信號該按鈕也會在稍後處理,就像點擊事件一樣。
如果先按下按鈕2(在啓用另一個按鈕之前出現消息框),則會注意到按鈕1在循環運行時未被禁用,但在消息框顯示之前它將被禁用,在消息框關閉之後保持這樣。
http://jsfiddle.net/u334tz36/1/
所以,我認爲沒有什麼解決。其實這兩個事件處理程序並不是在同一時間運行,而是在彼此之後運行,所以可能根本就沒有問題。
解決方案:
如果你仍然認爲這是煩人,你想默默消耗的點擊,您可以使用定時器做到這一點。在下面的代碼中,該按鈕在處理程序中未啓用,但在超時後運行1ms。這樣,一旦事件處理程序完成,(響應)窗口將處理所有延遲的消息。按鈕2將顯示爲禁用,點擊被禁用的按鈕消耗(和丟棄),和1毫秒之後,該按鈕被激活:
window.enableTest2 = function()
{
document.getElementById('test2').disabled = false;
}
window.test1 = function()
{
document.getElementById('test2').disabled = true;
for (var i=0; i<1000000000; i++);
setTimeout(window.enableTest2, 1);
}
http://jsfiddle.net/u334tz36/2/
有趣的事情是,你只需要讓窗口有機會檢索單擊按鈕時發送的消息。要做到這一點,你根本不需要幾秒鐘,1毫秒就足夠了,甚至可以少用幾秒鐘。您只需更改事件的順序:首先處理與禁用按鈕相關的所有更新,然後執行事件處理程序。因爲setTimeout也是基於消息的,所以它也依賴於相同的更新機制(並且實際上可以通過運行代碼來延遲。所以基本上你通過設置超時來做什麼,是將代碼放在隊列末尾的超時中,不管延遲多短,這都不是時間問題,這是一個執行順序的問題。
所以,這是一個可能的解決方法,但就像我說的,我不認爲存在首先是一個問題
謝謝你這麼詳細的回答,如果可以的話,我會給予更多的讚揚,我將不得不降低測試期望。 – Argus9 2014-09-08 14:02:10