介紹
一個典型的資料輸入頁面通常由多種用於收集使用者輸入的表單區域和一個提交按鈕組成。要建立這樣的一個頁面,你要ASP.NET頁面上添加一些適當的Web控制項——一些TextBox和CheckBoxList,或許還有一個Button控制項。只要使用者介面部分完成後,該項目還需要建立一個事件處理過程來處理Button的點擊事件,並添加需要啟動並執行代碼…或許你要將資料存入資料庫中,或者是通過電子郵件將這些資訊發送給某人。
當填寫這樣的頁面時,你大概經曆過下面的一些事情:在你填寫TextBox時點擊了斷行符號鍵,該頁面就提交了。這是瀏覽器提供的一個功能,不需要動滑鼠就可以提交頁面。例如:如果你訪問Google,輸入焦點馬上就定位到搜尋方塊中,在你輸入完查詢內容後,你可以點擊斷行符號鍵查看結果。
雖然部分ASP.NET 開發人員認為表面上看當ASP.NET頁面點擊斷行符號後提交頁面會觸發頁面按鈕控制項的Click事件,有時候並非如此。在這篇簡短的文章裡,我們將會看到什麼情況下當使用者點擊斷行符號鍵提交頁面時,Button控制項的Click事件不會觸發,而且我們會看看實際的情況。繼續看,你會學到更多。
斷行符號鍵提交頁面的由來
(中間省略一段無關的話。。。)
當一個頁麵包含多個提交按鈕時,通過斷行符號鍵來提交頁面有一個潛在的問題。在這樣的情況下,當斷行符號鍵被點擊的時候,哪個按鈕應該與頁面的提交聯絡在一起?我的經驗顯示瀏覽器會使用在HTML標記裡面最早出現的按鈕。
使用斷行符號鍵提交頁面和Button控制項的Click事件 在有多個單行TextBox控制項的ASP.NET頁面中,當斷行符號鍵被點擊時,頁面被提交同時第一個顯示在HTML頁面上的Button控制項的Click事件將被激發。這就是我們所預期的。然而會有些古怪的事情發生在Internet Explorer上,如果頁面中只包含一個單行的TextBox,Button控制項的事件將不會被觸發!頁面提交了,但是Click事件沒有被處理——這是你用來處理使用者輸入的邏輯代碼的地方——沒有被執行,怎麼回事? 問題的關鍵在於一個只有單行的TextBox的頁面中點擊斷行符號鍵後,Internet Explorer提交Form控制項的方式。明確的說,Internet Explorer在提交的內容中不包含提交按鈕的名稱與按鈕的值。自從提交按鈕的名稱與值不被提交回伺服器端,ASP.NET伺服器不能判定是什麼導致了提交,因此不能激發對應的Button控制項的Click事件。 為了更好的理解這個問題,假設以下情況:我們有一個頁面,它包含了很多個名字從TextBox1到TextBoxN的單行TextBox和一個叫做btnSubmit的按鈕,按鈕的Value為Click Me!(按鈕的Value就是顯示在Button上面的文本)(在這裡,這些名字是根據Web控制項的ID號來取的)。當一個使用者填好頁面並在一個TextBox中點擊斷行符號鍵時,這個頁面會被提交,同時發送回下面的字串(包含在提交的內容中): TextBox1=Value1&TextBox2=Value2&&TextBoxN=ValueN&btnSubmit=Click Me! Value1…ValueN是輸入給TextBox1到TextBoxN的內容。 當ASP.NET的頁面被提交之後,它通過分析這個字串能夠知道這次提交是由於btnSubmit按鈕控制項所導致的。它會觸發Web控制項的Click事件,你的事件處理代碼也就可以執行了。如果你現在只有一個單行的文本輸入框,包含在提交內容中的字串會忽略掉btnSubmit=Click Me!。也就是說如果你只包含了一個叫做TextBox1的單行輸入框,你會得到下面的提交內容:
TextBox1=Value1
沒有資訊提到哪個按鈕觸發了這次提交,ASP.NET的伺服器端不能夠正確的觸發按鈕的Click事件。因此,如果你的頁面只包含一個單行文本輸入框(甚至還有另外的輸入控制項,例如CheckBoxList,RadioButtonList,DropDownList等等),使用InternetExplorer時,點擊斷行符號將不會觸發Button控制項的Click事件——其它瀏覽器,例如FireBox,總是會提交按鈕的值與名稱,即使只有一個文本輸入框。 提供一個例子
如果你的網站有一個頁麵包含了單個TextBox控制項,使用Internet Explorer的使用者將不能在TextBox中點擊斷行符號而得到適當的效果。也就是說,他們點擊斷行符號鍵頁面會被提交,但是無論你在按鈕的Click事件處理過程中寫了什麼樣的代碼都不會執行。因此,對於使用者來說好像什麼都沒有發生過。 為了克服這個問題,你可以使用下面的方法——只要在頁面中增加另一個TextBox控制項。這樣會讓Internet Explorer在點擊斷行符號鍵時,發送回Button控制項的值與名稱。當然,你不會希望讓使用者看到兩個TextBox,所以使用一點CSS來隱藏第二個TextBox。也就是說,如果原來的代碼如下:
<form runat="server">
Name: <asp:TextBox runat="server" id="txtName" />
<br />
<asp:Button runat="server" Text="Click Me!" />
</form> 增加另外一個TextBox控制項來解決這個IE中斷行符號鍵的問題,但把第二個TextBox隱藏起來,你的使用者只會看到一個: <form runat="server">
Name: <asp:TextBox runat="server" id="txtName" />
<br />
<asp:TextBox runat="server" style="visibility:hidden;display:none;" />
<asp:Button runat="server" Text="Click Me!" />
</form>
到此為止啦!
結論
在這篇文章中,我們分析了使用某些瀏覽器在一些情況下,使用者點擊斷行符號鍵很可能會導致頁面提交但卻不會觸發Button控制項的Click事件。不建立包含單個TextBox控制項的頁面就可以很簡單的解決這個局限性問題。更適當的說,如果在一些情況下你只要一個TextBox,增加一個“人造”的TextBox——一個僅僅用來解決這個問題的TextBox。如上面所討論的,你可以很簡單的使用一點CSS來隱藏這些“人造”的TextBox。 另外,關於斷行符號鍵與頁面提交的問題,也可以用JavaScript來禁止或確保斷行符號鍵來提交頁面,你一定需要看看下面的文章: FORM submission and the ENTER key? Using JavaScript to prevent or trigger form submission when ENTER is hit FAQs relating to 'Pressing Enter Key for Form Submission'