闲话多提交按钮HTML表单
2012-12-25 16:14
218 查看
在 Web 应用中,最常用的服务器端与客户端的数据交互是通过提交 HTML 表单实现的。以 HTML 4.01 为例,规定当表单提交时,会将
的当前取值提交到服务器。所谓成功控件需要有以下几个条件(但不仅限于此):
必须有控件名字,即必须包含 name 属性
如果表单中有多个提交按钮,只有被点击的那个按钮可以是成功的
不能是禁用状态,即不含 disabled 属性
不是 Reset button
现在我们考虑一下这样的场景,在某个表单中我们需要用到多个提交按钮(Submit button),就如同 WordPress 后台写文章那样的表单,我们在编辑完文章内容后,可以选择保存草稿或是直接发布。下面图中所示是一个简化的发布页面,可以填写文章标题、内容之后选某一种提交形式:
对应的 HTML 片段可以是这样:
HTML
为了在提交时能区分是保存还是发布,需要通过 JavaScript 来为不同的按钮绑定不同的操作:
JavaScript
那么提交的数据中如何来区分是保存草稿还是发布?通常我们会在
HTML
这样在 JS 中就只需要为按保存方式提交作相应处理:
JavaScript
这样如果按 Save Draft,那么 POST 出去的数据就应该是:
title=blah&content=blahblah&post-status=draft
OK,这样的确已经可以正常工作了,但是总觉得让人有些不爽:这么简单的工作为什么还要通过脚本来实现?有没有想过为什么要这样实现呢?事实上,因为在文章开始的地方提到的 HTML 规范中定义了一个表单中有多个提交按钮的情况下,只有一个可以是成功控件从而提交自己的数据值,也就是说,我们给提交按钮加上相同的 name 属性,只有一个按钮会提交相应的数据。那何必还需要隐藏控件?应该只需要这样:
HTML
像这样把两个提交按钮的 name 属性都设为 post-status,就可以像服务器发送唯一的 post-status 值了,但有一个问题:post-status 的值只能和按钮上的文字一样了,给 Web 应用的i18n 带来了很大的不便。其实 HTML 规范也考虑到了这个问题,这就是为什么我们会有
元素。HTML 中的按钮共有三种类型:
submit buttons
reset buttons
push buttons
前两个不用说,第三种按钮没有默认的数据交互行为,需要依赖脚本才能起到作用。一般情况下我们使用的都是 type 属性分别为 submit / reset / button 的
value 应当是分离的:
HTML
看上去很不错,不是么?可是很不幸,我们又遇到麻烦了:在 IE6/7 下,这样的方法完全不能工作。在 IE6 下,用这样的方式按 Save Draft 按钮,POST 出的参数值为:
title=blah&content=blahblah&post-status=Save+Draft&post-status=Publish
在 IE7 下,则是:
title=blah&content=blahblah&post-status=Save+Draft
可以看到,IE6/7 错误地把
替换 innerHTML,但这样在网速比较慢的情况下(就是大多数情况下)会出现下面这样的画面:
这显然也是不能让人接受的。就是没有一个完美的方案,就是这样,所以又回到我们开头的地方了。用隐藏控件来 hold 住提交方式参数,用脚本来给它赋值,又变成了看起来最通用最简单的方案了。
另外有一种观点认为,一个表单就不该有多个提交按钮,提交按钮不该携带任何参数值,完全可以换成单选框、下拉菜单等等等等方式来实现。但实际上多个提交按钮在很多时候可以减少用户的交互操作,并且更为直观,绝对是有其存在价值的。拿 WordPress 的文章发布方式来说,现在就是多提交按钮的:
如果改成下面这样,就感觉十分别扭了:
总结一下:如果你可以抛弃 IE6/7,那么恭喜你,用最简单优雅的方式去实现吧!如果不能,那么,还是老老实实地用隐藏控件吧,慢慢等着 IE6/7 入土为安吧。
很久没写东西了,有点虎头蛇尾,其实没多少内容,发发牢骚而已。
Update: 欲了解更多关于按钮数据交互行为的浏览器差异可以阅读这篇文章。
<form>元素中的Successful controls
的当前取值提交到服务器。所谓成功控件需要有以下几个条件(但不仅限于此):
必须有控件名字,即必须包含 name 属性
如果表单中有多个提交按钮,只有被点击的那个按钮可以是成功的
不能是禁用状态,即不含 disabled 属性
不是 Reset button
现在我们考虑一下这样的场景,在某个表单中我们需要用到多个提交按钮(Submit button),就如同 WordPress 后台写文章那样的表单,我们在编辑完文章内容后,可以选择保存草稿或是直接发布。下面图中所示是一个简化的发布页面,可以填写文章标题、内容之后选某一种提交形式:
对应的 HTML 片段可以是这样:
HTML
1 2 3 4 5 6 | <form action="http://localhost/blog/new-post" method="POST"> <input type="text" name="title" id="title" /><br /> <textarea name="content" id="content" cols="30" rows="10"></textarea><br /> <input type="submit" id="save-post" value="Save Draft" /> <input type="submit" id="publish" value="Publish" /> </form> |
JavaScript
1 2 3 4 5 67 | //using jQuery $('#save-post').click(function() { //按保存草稿方式提交 }); $('#publish').click(function() { //按发布方式提交 }); |
<form>中添加一个隐藏的控件来保存这个状态,像这样:
HTML
<!-- value 可以是 publish 或 draft,默认为 publish --> <input type="hidden" name="post-status" id="post-status" value="publish" /> |
JavaScript
1 2 3 4 | //using jQuery $('#save-post').click(function() { $('#post-status').val('draft'); }); |
title=blah&content=blahblah&post-status=draft
OK,这样的确已经可以正常工作了,但是总觉得让人有些不爽:这么简单的工作为什么还要通过脚本来实现?有没有想过为什么要这样实现呢?事实上,因为在文章开始的地方提到的 HTML 规范中定义了一个表单中有多个提交按钮的情况下,只有一个可以是成功控件从而提交自己的数据值,也就是说,我们给提交按钮加上相同的 name 属性,只有一个按钮会提交相应的数据。那何必还需要隐藏控件?应该只需要这样:
HTML
1 2 3 4 5 6 | <form action="http://localhost/blog/post" method="POST"> <input type="text" name="title" id="title" /><br /> <textarea name="content" id="content" cols="30" rows="10"></textarea><br /> <input type="submit" name="post-status" id="save-post" value="Save Draft" /> <input type="submit" name="post-status" id="publish" value="Publish" /> </form> |
<button>
元素。HTML 中的按钮共有三种类型:
submit buttons
reset buttons
push buttons
前两个不用说,第三种按钮没有默认的数据交互行为,需要依赖脚本才能起到作用。一般情况下我们使用的都是 type 属性分别为 submit / reset / button 的
<input>元素,而
<button>元素就是用来为这三类
<input>提供更多渲染可能性的,
<button>中可以插入其他的 HTML 元素,比如可以加入
<img>来给按钮增加一个图标,所以显然也可以使用任何你想使用的文本作为按钮上显示的文字。这个文字和按钮的取值
value 应当是分离的:
HTML
<button type="submit" name="post-type" id="save" value="draft">Save Draft</button> <button type="submit" name="post-type" id="publish" value="publish">Publish</button> |
title=blah&content=blahblah&post-status=Save+Draft&post-status=Publish
在 IE7 下,则是:
title=blah&content=blahblah&post-status=Save+Draft
可以看到,IE6/7 错误地把
<button>的 innerHTML 当作了 value 发送出去了,而 IE6 甚至把没有点击的按钮也看作成功。WTF!本来很优雅的代码在现实中却是无法完美工作的。有人写了个针对 IE6/7 的 hack 来解决这个问题,即在
<button>的点击事件中,disable 同一表单内的其他
<button>并且用其 value
替换 innerHTML,但这样在网速比较慢的情况下(就是大多数情况下)会出现下面这样的画面:
这显然也是不能让人接受的。就是没有一个完美的方案,就是这样,所以又回到我们开头的地方了。用隐藏控件来 hold 住提交方式参数,用脚本来给它赋值,又变成了看起来最通用最简单的方案了。
另外有一种观点认为,一个表单就不该有多个提交按钮,提交按钮不该携带任何参数值,完全可以换成单选框、下拉菜单等等等等方式来实现。但实际上多个提交按钮在很多时候可以减少用户的交互操作,并且更为直观,绝对是有其存在价值的。拿 WordPress 的文章发布方式来说,现在就是多提交按钮的:
如果改成下面这样,就感觉十分别扭了:
总结一下:如果你可以抛弃 IE6/7,那么恭喜你,用最简单优雅的方式去实现吧!如果不能,那么,还是老老实实地用隐藏控件吧,慢慢等着 IE6/7 入土为安吧。
很久没写东西了,有点虎头蛇尾,其实没多少内容,发发牢骚而已。
Update: 欲了解更多关于按钮数据交互行为的浏览器差异可以阅读这篇文章。
相关文章推荐
- html中的button按钮调用js函数和提交表单传递参数
- html中多个按钮提交表单
- HTML同一个table中不同的按钮提交不同表单
- HTML 中按钮作为form表单元素提交特性两则 --- 参HTML考标准分析
- html中的单选按钮radio如何实现可同时选中多个值进行表单提交
- 如何在改变了html表单里的“提交按钮的背景图片”
- html表单图片按钮提交
- Html(4)表单,单选框、复选框,提交、重置按钮
- html基础-表单控件、密码框、单选按钮、复选框、多行文本框、下拉列表、按钮(提交、图片、重置)
- 前端之路——第三篇:列表、表单、提交按钮、html布局、css的display,制造第一个表单提交案例
- HTML表单元素2(普通按钮、提交按钮、重置按钮、图像提交按钮、HTML的按钮标签<button>、练习)
- html表单(文本框、密码、单选、复选、提交、重置、普通、隐藏、文件按钮、下拉选项)
- HTML的form表单自动提交
- ASP 如何获取HTML表单提交信息
- 在ASP.Net2.0中多个通过回车键提交表单时执行特定的button按钮事件
- 表单提交到下一个页面后,再点击IE上的后退,如何能让表单内容再次显示出来?(以及当前页禁止IE返回按钮js)
- php接受通过HTML表单提交的信息时
- 一个表单的多按钮提交
- asp.net 防止用户通过后退按钮重复提交表单
- 把HTML表单提交的数据转化成XML文件