寫了多年的網頁程式,自認精通Javascript,卻在今天又再一次體會活到老學到老的真諦。
同事請我幫忙抓一隻難纏的蟲,程式參考自MSDN一篇關於長時間網頁(Long Run)等待狀態顯示的Design Pattern,目的在避免使用者久候不耐的感受,實務上一些執行時間高達數十秒到數分鐘的網頁,總是讓人搞不清楚是當機還是在處理中。如果在等待的同時可以顯示一些”安撫使用者”的進度資料,可以減少網頁被使用者放棄的機率。
原文中有一段Javascript location.href轉向的特殊用法,讓我頓時丈二金鋼摸不著腦袋。我把相當的邏輯簡化成以下兩個網頁:
Start.htm [用來觸發Long Run網頁,並顯示等待秒數安撫使用者]
<html><body>
<button onclick="process();">Process</button>
Time: <span id=msg></span>
<script>
function process() {
        setInterval("showTimer();",1000);
        location.href="Process.aspx" mce_href="Process.aspx";
}
var i=0;
function showTimer() {
        i++;
        msg.innerText=i;
}
</script></body></html>
Process.aspx [模擬Long Run網頁,Delay 10秒後顯示Finished!]
<%@ Page Language="C#"%>
<html><body>
<% System.Threading.Thread.Sleep(10000); %>
Process Finished!
</body></html>
依我過去的認知,在location.href=”…”之後,目前的網頁應該就會Unload,瀏覽器會立即連上新網頁,若新網頁耗時很久,則使用者勢必會有一段時間看著白色的網頁發呆。但事實不然….
反覆做了幾個測試,即使Process.aspx先Response.Write一些文字,利用Response.Buffer=false或Response.Flush先送一部分內容到IE,Thread.Sleep後再送出第二段文字後結束,結果還是一致的--當使用location.hreflocation.replace導向其他網頁後,IE會停留在原網頁上,一直到新網頁內容傳輸全部完成為止。
因此,上述的Start.htm程式中的setInterval會啟動讀秒,等待Process.aspx完全執行結束後,IE才會用Process.aspx的網頁內容取代Start.htm。實際Demo可以看這裡
今天的觀察所得,一下子推翻了多年來深信不移的概念,幸好早年幾位嗜賭成性的老友Max, Ryan, 小毛不在,不然可能已經輸掉一客牛排。沒想到自稱老鳥還是被電得哇哇叫,只能說技術領域實在太浩瀚了,永遠不要自滿,心態才會健康!
另外,今天還學到一個新method—location.replace(),跟location.href一樣,可以用來Redirect,但最大的不同是replace後新URL可以取代Browser的歷史記錄,也就是被取代掉的URL將從回上一頁的清單中消失,如果你不想要某個網頁被Reload,這也是個可以考量的方法。

Comments

# by steve

我以前寫過這樣的東西,很好玩<BR/>如果不想用數字,也可以依序用/-\|/-\|<BR/>就會看起來像在旋轉^^<BR/><BR/>&lt;HTML&gt;<BR/>&lt;BODY&gt;<BR/>目前處理到第&lt;span id="showText"&gt;0&lt;/span&gt;筆<BR/>&lt;%<BR/> i = 0<BR/> Do Until i &gt; 1000000<BR/> i = i + 1<BR/> If (i Mod 100) = 0 Then<BR/>%&gt;<BR/>&lt;SCRIPT LANGUAGE="JavaScript"&gt;<BR/>&lt;!--<BR/> document.all("showText").innerText = "&lt;%=i%&gt;";<BR/>//--&gt;<BR/>&lt;/SCRIPT&gt;<BR/>&lt;%<BR/> response.flush<BR/> End If <BR/> Loop<BR/> <BR/>%&gt;<BR/>&lt;/BODY&gt;<BR/>&lt;/HTML&gt;

# by Darkthread

嘿... 這倒是個直覺、簡單、有效的好方法。<BR/>這年頭AJAX當道,如果不想自己麻煩,可以找到一狗票現成的程式範例。Google一下AJAX Progress Bar,就能找到一堆。

# by Joe64

黑暗大,Demo的連結好像壞掉了也

# by futnpav

<% System.Threading.Thread.Sleep(10000); %> 是在server端执行的吧。。。

Post a comment