原文章:Enter and the Button Click Event
http://aspnet.4guysfromrolla.com/articles/060805-1.aspx
介绍
一个典型的数据输入页面通常由多种用于收集用户输入的表单区域和一个提交按钮组成。要创建这样的一个页面,你要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 >
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 >
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'
Happy Programming!