當我們在網頁上設計了表單, 讓使用者填寫資料, 使用者通常有很大的機率會因為各式各樣的原因而意外地跳出頁面。如果表單很簡單, 或者使用者根本還沒有填寫什麼資料, 那麼使用者就算不小心離開頁面, 也不會有什麼損失。但是如果使用者已經填寫了很多資料 (例如姓名、地址、電話等等), 但是在他按下確認按鈕之前, 卻不小心按到上一頁、下一頁、關閉分頁、關閉視窗等按鈕, 那麼不管他使用何種方式回到這一頁, 他曾經填寫的資料可能都無法救回來。除非你只寫網頁給別人用, 自己從不上網, 否則我相信你一定也遇過這種切身之痛 -- 花了幾十分鐘, 甚至幾個小時打進去的文章, 卻由於一個不小心的動作, 讓自己辛苦的成果在瞬間徹底消失了! 不瞞你說, 我自己遇過太多次此種痛苦的經驗, 導致我曾有一段很長的時間, 即使只是填入自己家裡的住址而已, 我也一定要開啟 Notepad 來打字(而且還要隨時存檔), 打完之後再把文字複製貼回網頁...
當我們在網頁上設計了表單, 讓使用者填寫資料, 使用者通常有很大的機率會因為各式各樣的原因而意外地跳出頁面。如果表單很簡單, 或者使用者根本還沒有填寫什麼資料, 那麼使用者就算不小心離開頁面, 也不會有什麼損失。但是如果使用者已經填寫了很多資料 (例如姓名、地址、電話等等), 但是在他按下確認按鈕之前, 卻不小心按到上一頁、下一頁、關閉分頁、關閉視窗等按鈕, 那麼不管他使用何種方式回到這一頁, 他曾經填寫的資料可能都無法救回來。
除非你只寫網頁給別人用, 自己從不上網, 否則我相信你一定也遇過這種切身之痛 -- 花了幾十分鐘, 甚至幾個小時打進去的文章, 卻由於一個不小心的動作, 讓自己辛苦的成果在瞬間徹底消失了! 不瞞你說, 我自己遇過太多次此種痛苦的經驗, 導致我曾有一段很長的時間, 即使只是填入自己家裡的住址而已, 我也一定要開啟 Notepad 來打字(而且還要隨時存檔), 打完之後再把文字複製貼回網頁。
或許你認為使用者自己跳出網頁, 並不關自己的事呀! 話是沒錯, 並沒有人說那是你造成的。但是, 請將心比心, 如果你運用了某種機制, 讓使用者犯下錯誤的機會減少, 那麼在無形中你所設計的網頁就更容易得到使用者的信任, 或者, 至少你不會被自己設計的網頁氣死。
其實所有網頁程式設計師都應該了解並改善這個問題 -- 如果你希望你設計的網頁可以稱得上是 User-friendly 的話。
像這類問題, 一般我們可以採用以下幾個對策:
- 在表單裡加上「儲存」按鈕, 讓使用者可以隨時按此按鈕把自己輸入的文字予以儲存, 以便隨時修改。
- 在每個控制項的 OnChange 之類的事件中寫入程式, 將使用者的所有輸入都存入 ViewState 或是 Cookies 裡面, 確保使用者回到本頁之後資料依然存在。
- 判斷使用者是不是在未存檔之前就跳離本頁。如果是的話, 發出警告, 以避免使用者無意中按到關閉或上下頁等按鈕。
以上三種做法都各有利弊。通常我們可能會挑選一種來實作, 也可能三種方法都做。
自從 Scott Mitchell 在 2004 年寫了「Using ASP.NET to Prompt a User to Save When Leaving a Page」這篇文章之後, 作者所介紹的方法就被我使用在我自己的網站裡面。雖然我曾經一度想要把它以 jQuery 來改寫, 但是一直都懶得去做 -- 反正它一直也運作得很好。
不過前幾天我才發現似乎並不是所有人都知道 Scott 的這篇文章。在 MSDN 論壇上, 恰巧有朋友問到了這個問題, 而某位 MVP 明明已經把 Scott 的文章介紹給那位發問人, 但是他還是繼續問著相同的問題。我突然了解, 或許是因為 Scott 寫的是英文, 而它的原始程式使用的是 VB, 以致於並不是所有人都看得懂這篇文章。
在徵求原作者的同意之後, 我在此把我改寫的 C# 版本附上來, 並且簡單的說明一下程式的用法。步驟如下:
- 開啟 VS2010, 建立一個新網站
- 在方案總管裡面加入一個類別 (你應該會被要求把程式放在 App_Code 資料夾之下)
- 修改一下這個類別檔案, 讓它繼承 System.Web.UI.Page (請參考原始檔案中 /App_Code/BasePage.cs 這個檔案的寫法)
- 在你所有要提供本文所描述的功能的網頁中, 開啟其 .aspx.cs 檔案, 讓其類別繼承 BasePage (請參考原始檔案中 Default.aspx.cs 這個檔案的寫法)
- 在這些 .aspx.cs 檔案中的 Page_Load 事件處理函惑中, 為所有將受到監控的控制項加上 MonitorChanges 方法 (請參考原始檔案中 Default.aspx.cs 這個檔案中的 Page_Load 裡的寫法)
- 仿上, 如果你有儲存按鈕, 那麼為它加上 BypassModifiedMethod 方法 (當然, 儲存的功能你必須自己寫) (請參考原始檔案中 Default.aspx.cs 這個檔案中的 Page_Load 裡的寫法)
- 如果你在網頁中有什麼超連結或按鈕是不想受到監控的, 可以在它的 OnClick 事件中直接下達 Response.Redirect (請參考原始檔案中 Default.aspx.cs 這個檔案中的 LinkButton1_Click 裡的寫法)
如果一切順利的話, 當你一旦在網頁中做了什麼修改 (包括在文字框裡輸入文字、勾選 ButtonList 等等), 以下種種動作都會觸發警示:
- 按下瀏覽器的上一頁或下一頁
- 關閉分頁
- 關閉視窗
- 按下前往其它網頁的連結 (LinkButton1 例外)
觸發警示的畫面如下:
相關文章:
- Using ASP.NET to Prompt a User to Save When Leaving a Page
- An Update on Prompting a User to Save When Leaving an ASP.NET Page
- [jQuery]離開表單或網頁時向使用者確認