黄子涵

第 12 章 表单

表单是HTML中获取用户输入的手段。它对于Web应用系统极其重要,然而HTML定义的功能落后于表单的使用方式已有多年。在HTML5中,整个表单系统已经彻底改造过,面貌焕然一新,标准的步伐已经跟上了表单的应用实践。

这里介绍的是HTML表单的基础知识。从定义一个非常简单的表单开始,通过对它的扩充演示如何配置和控制表单工作的方式。

制作基本表单

制作一个基本的表单需要三个元素:form、input和button元素。代码清单1展示了一个含有简单表单的HTML文档。

代码清单1 一个简单的HTML表单

<!DOCTYPE HTML>
<html>
    <head>
        <title>黄子涵</title>
        <meta name="作者" content="黄子涵"/>
        <meta name="描述" content="黄子涵是帅哥!"/>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <link rel="shortcut icon" href="favicon.ico" type="image/x-icon"/>
    </head>
    <body>
        <form method="post" action="http://120.77.46.246/form">
            <input name="fave"/>
            <button>黄子涵的按钮</button>
        </form>
    </body>
</html>

其显示效果如下图所示。

image

这个表单实在太简单了,没有多少用处。

定义表单

先从form元素讲起,该元素表示HTML页面上的表单。下表概括了form元素。

form元素

image

目前只要知道form元素告诉浏览器它处理的是HTML表单就行了。

第二种关键元素是input,其用途是收集用户输入数据。从上图可以看到,那个input元素在浏览器中显示为一个简单的文本框。用户就在这个文本框中输入内容。这是最基本的一种input元素。后面会介绍收集用户输入数据的多种选择(包括HTML5中新增的一些很棒的特性),下表概括了input元素。

input元素

image

input元素的属性多达29个,具体有哪些可用取决于type属性的值。


提示

除了input元素,还有其他一些元素可以用来收集用户输入的数据。

前面的例子中要讲的最后一个元素是button。用户需要有一种方法告诉浏览器:所有数据已经输入完毕,该把它们发给服务器了。这个事情多半是用button元素来做(不过还有一些其他办法可用)。下表概括了button元素。


button元素

image

button元素有多种用途。该元素用在form元素中且没有设置任何属性时,其作用是告诉浏览器把用户输入的数据提交给服务器。

查看表单数据

这个示例需要有一个接收浏览器发送的数据的服务器。

代码清单2 脚本文件formecho.js

var http = require('http');
var querystring = require('querystring');

http.createSever(function (req, res)) {
    switch (req.url) {
        case '/form':
        if(req.method == 'POST') {
            console.log("[200]" + req.method + "to" + req.url);
            var fullBody = '';
            req.on('data', function(chunk) {
                fullBody += chunk.toString();
            });
            req.on('end', function() {
                res.writeHead(200, "OK", {'Content-Type': 'text/html'});
                res.write('<html><head><title><title><head><body>');
                res.write('<style>th, td {text-align:left; padding:5px; color:black}\n');
                res.write('th {background-color:grey; color:white; min-width:10em}\n');
                res.write('td {background-color:lightgrey}\n');
                res.write('caption {font-weight:bold}</style>');
                res.write('<table border="1"><caption>Form Data</caption>');
                res.write('<tr><th>Name</th><th>Value</th>');
                var dBody = querystring.parse(fullBody);
                for (var prop in dBody) {
                    res.write("<tr><td>" + prop + "</td><td>" + dBody[prop] + "</td></tr>");
                }
                res.write('</table></body></html>');
                res.end();
            });
        } else {
            console.log("[405]" + req.method + "to" + req.url);
            res.writeHead(405, "Method not supported", {'Content-Type': 'text/html'});
            res.end('<html><head><title>405 - Method not supported</title></head><body>' +
                    '<h1>Method not supported.</h1></body></html>');
        }
        break;
      default:
        res.writeHead(404, "Not found", {'Content-Type': 'text/html'});
        res.end('<html><head><title>405 - Not found</tile></head><body>' +
                '<h1>Not found.</h1><body></html>');
        console.log("[404]" + req.method + "to" + req.url);
    };
}).listen(8080);

这个脚本将浏览器发来的数据汇总并返回一个简单的HTML文档,在文档中以HTML表格的形式将那些数据显示出来。它在8080端口监听浏览器的连接请求,并且只处理浏览器用HTTP POST方法发送到/form这个URL的表单数据。这个脚本保存在一个名为formecho.js的文件中。要运行这个脚本程序,可在服务器上打开一个命令窗口并输入如下命令:

bin\node.exe formecho.js

titan服务器运行的操作系统是Windows Server 2008 R2。读者如果使用其他操作系统的话,用来启动Node.js的命令会有所不同。在示例表单的文本框中输入Apples然后按下Submit Vote按钮提交表单,服务器端脚本的输出内容在浏览器中显示的结果如下图所示。(这里弄了很久都搞不明白,所以放弃了)

结果中只有一项数据,这是因为在示例表单中只有一个input元素。表格的Name列中显示的值为fave,它正是为input元素的name属性设置的值。表格的Value列中显示的值为Apples,它正是按下Submit Vote按钮之前在文本框中输入的内容。后面制作更复杂的表单时,Node.js脚本的输出信息都将以表格形式显示。

配置表单

前面已经制作过一个包含简单表单的HTML文档,并用Node.js显示了发送给服务器的数据。现在该介绍一下可用于表单及其内容的各种基本配置选项了。

配置表单的action属性

action属性说明了提交表单时浏览器应该把从用户收集的数据发送到什么地方。我想把数据提交给自己编写的Node.js脚本处理,所以要把表单发至开发服务器titan上位于8080端口的/form这个URL。代码清单1中的表单已经这样做了:


如果不设置form元素的action属性,那么浏览器会将表单数据发到用以加载该HTML文档的URL。这看似毫无意义,其实不然,好几个流行的Web应用系统开发框架都依赖于这个特性。

如果为action属性指定的是一个相对URL,那么该值会被嫁接在当前页的URL的后面。代码清单3示范了如何用base元素设置表单数据的发送目的地。

代码清单3 使用base元素设置表单数据的发送目的地

<!DOCTYPE HTML>
<html>
    <head>
        <title>黄子涵</title>
        <meta name="作者" content="黄子涵"/>
        <meta name="描述" content="黄子涵是帅哥!"/>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <link rel="shortcut icon" href="favicon.ico" type="image/x-icon"/>
        <base href="http://120.77.46.246"/>
    </head>
    <body>
        <form method="post" action="/form">
            <input name="fave"/>
            <button>黄子涵的按钮</button>
        </form>
    </body>
</html>

image

警告

base元素将影响HTML文档中所有的相对URL,而不只是form元素。

配置HTTP方法属性

method属性指定了用来将表单数据发送到服务器的HTTP方法。允许的值有get和post这两个,它们分别对应于HTTP的GET和POST方法。未设置method属性时使用的默认值为get。这有点令人遗憾,因为大多数表单都需要用HTTP POST方法。前面的例子中为表单指定的正是post这个值:


GET请求用于安全交互(safe interaction),同一个请求可以发起任意多次而不会产生额外作用。POST请求则用于不安全交互,提交数据的行为会导致一些状态的改变。对于Web应用程序多半釆用后一种方式。这些规矩是W3C(World Wide Web Consortium,万维网联盟)定的,参www.w3.org/Provider/Style/URI 。

一般而言,GET请求应该用于获取只读信息,而POST请求则应该用于会改变应用程序状态的各种操作。使用恰当的请求很重要。如果拿不准该用哪个,宁可谨慎一点,就用POST方法好了。

提示

Node.js脚本只响应POST请求。

配置数据编码

enctype属性指定了浏览器对发送给服务器的数据采用的编码方式。该属性可用的值有三个,如下表所示。

enctype属性允许的值

说明
application/x-www-form-urlencoded 这是未设置enctype属性时使用的默认编码方式。它不能用来将文件上传到服务器
multipart/form-data 该编码方式用于将文件上传到服务器
text/plain 该编码方式因浏览器而异

为了搞清这些编码方式的工作机制,需要先在表单中再添加一个input元素,如代码清单4所示。

代码清单4 在表单中添加一个input元素

<!DOCTYPE HTML>
<html>
    <head>
        <title>黄子涵</title>
        <meta name="作者" content="黄子涵"/>
        <meta name="描述" content="黄子涵是帅哥!"/>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <link rel="shortcut icon" href="favicon.ico" type="image/x-icon"/>
    </head>
    <body>
        <form method="post" action="/form">
            <input name="fave"/>
            <input name="name"/>
            <button>黄子涵的按钮</button>
        </form>
    </body>
</html>

添加第二个input元素是为了从用户那里收集两项数据。读者可能已经看出,这里要设计的表单是用来让用户为自己喜欢的水果投票的。新增的input元素用来获取用户的姓名。从代码清单中可以看到,该元素的name属性的值被设置成了name。为演示各种表单编码方式的效果,实验中将把表单的enctype属性分别设置为每一种可用的编码类型。每一次在文本框中输入的数据都是相同的。第一个文本框中输入的是Apples,第二个文本框中输入的是Adam Freeman(姓氏和名字之间有一个空格)。

application/x-www-form-urlencoded编码

这是默认的编码方式,除了不能用来上传文件到服务器外,它适用于各种类型的表单。每项数据的名称和值都与URL采用同样的编码方案(这是该编码方式名称中urlencoded这个部分的由来)。示例表单的数据釆用这种编码后的结果如下:

fave=Apples&name=Adam+Freeman

其中的特殊字符已经替换成了对应的HTML实体。数据项的名称和值以等号(=)分开,各组数据项间则以符号&分开。

multipart/form-data编码

multipart/form-data编码走的是另一条路子。它更为冗长,处理起来更加复杂。这也是它一般只用于需要上传文件到服务器的表单的原因————这个任务用默认编码方式无法办到。示例表单的数据采用这种编码方式的结果如下:

------WebkitFormBoundary2qgCsuH4ohZ5eObF 
Content-Disposition:form-data;name="fave"

Apples

------webKitFormBoundary2qgCsuH4ohZ5eObF 
Content-Disposition:form-data;name="name"

Adam Freeman

------WebKitFormBoundary2qgCsuH4ohZ5eObF--

fave=Apple 

name=Adam Freeman
text/plain编码

这种编码要谨慎使用。对于在这种方案中数据应该如何编码并没有正式的规范,主流浏览器各有各的数据编码方法。例如,Chrome使用与application/x-www-form-urlencoded方案一样的数据编码方法,而Firefox则将数据编码成如下形式:

fave=Apple

name=Adam Freeman

在这个结果中,每个数据项占据一行,特殊字符并未进行编码。建议不要使用这种编码方案, 各种浏览器实现它的方式各不相同,因此其结果难以预料。

控制表单的自动完成功能

浏览器可以记住用户输入表单的数据,并在再次遇到类似表单的时候自动使用这些数据帮用户填写。这种技术可以让用户免于反复输入同样的数据之苦。这方面的一个典型例子是用户在线购买商品或服务的时候输入的姓名和送货信息。每个网站都有自己的购物车和注册程序,但是浏览器可以使用用户在其他表单中输入过的数据加快结账过程。用以判断哪些数据可以重复使用的技术因浏览器而异,不过一种常用的方法是查看input元素的name属性。

一般来说,表单的自动完成功能有益于用户,对Web应用系统也有一点帮助。不过有时网页作者并不想让浏览器自动填写表单。代码清单5示范了如何使用form元素的autocomplete属性达到这个目的。

代码清单5 将form元素的autocomplete属性设置为禁用

<!DOCTYPE HTML>
<html>
    <head>
        <title>黄子涵</title>
        <meta name="作者" content="黄子涵"/>
        <meta name="描述" content="黄子涵是帅哥!"/>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <link rel="shortcut icon" href="favicon.ico" type="image/x-icon"/>
    </head>
    <body>
        <form autocomplete="off" method="post" action="http://120.77.46.246/form">
            <input name="fave"/>
            <input name="name"/>
            <button>黄子涵的按钮</button>
        </form>
    </body>
</html>

image

autocomplete属性允许的值有两个:on和off。如果不设置这个属性的话,其默认值为on,表示允许浏览器填写表单。

input元素也有autocomplete属性,可以用于单个元素的自动完成功能,如代码清单6所示。

代码清单6 设置input元素的autocomplete属性

<!DOCTYPE HTML>
<html>
    <head>
        <title>黄子涵</title>
        <meta name="作者" content="黄子涵"/>
        <meta name="描述" content="黄子涵是帅哥!"/>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <link rel="shortcut icon" href="favicon.ico" type="image/x-icon"/>
    </head>
    <body>
        <form autocomplete="off" method="post" action="http://120.77.46.246/form">
            <input autocomplete="on" name="fave"/>
            <input name="name"/>
            <button>黄子涵的按钮</button>
        </form>
    </body>
</html>

image

form元素的autocomplete属性设置的是表单中的input元素默认的行为方式。而各个input元素在该属性上的设置可以覆盖这个默认行为方式。上面的代码清单正是这样做的。此例在form元素上禁用了自动完成功能,但在第一个input元素上————仅是在这个元素上,又重新开启了该功能。至于第二个input元素,因为没有设置autocomplete属性,所以釆用的是form层面的设置。

一般来说,最好让自动完成功能保持开启状态。用户习惯让浏览器自动填写表单,而且在网上办理任何一种业务时往往都会用到好几个表单。关闭这个功能干涉了用户的偏好和工作习惯。有些网站对信用卡数据禁用自动完成功能,这个更有意义一点。不过即便如此,这种做法也要谨慎使用,要充分考虑各种理由。

指定表单反馈信息的目标显示位置

默认情况下浏览器会用提交表单后服务器反馈的信息替换表单所在的原页面。这可以用form元素的target属性予以改变。该属性的工作机制与a元素的target属性一样。可供选择的目标如下表所示。

fonn元素的target属性值

说明
_blank 将浏览器反馈信息显示在新窗口(或标签页)中
_parent 将浏览器反馈信息显示在父窗框组中
_self 将浏览器反馈信息显示在当前窗口中(这是默认行为)
_top 将浏览器反馈信息显示在顶层窗口中
<frame> 将浏览器反馈信息显示在指定窗框中

这些值每一个都代表着一种浏览环境。_blank_self这两个值不言而喻。其他值则与窗框的使用相关。代码清单7示范了如何设置form元素的target属性。

代码清单7 使用target属性

<!DOCTYPE HTML>
<html>
    <head>
        <title>黄子涵</title>
        <meta name="作者" content="黄子涵"/>
        <meta name="描述" content="黄子涵是帅哥!"/>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <link rel="shortcut icon" href="favicon.ico" type="image/x-icon"/>
    </head>
    <body>
        <form target="_blank" method="post" action="http://120.77.46.246/form">
            <input autocomplete="on" name="fave"/>
            <input name="name"/>
            <button>黄子涵的按钮</button>
        </form>
    </body>
</html>

此例将target设置为_blank,让浏览器将服务器的反馈信息显示在新窗口或标签页中。这个修改的效果如下图所示。

image

设置表单名称

name属性可以用来为表单设置一个独一无二的标识符,以便使用DOM(Document Object Model,文档对象模型)时区分各个表单。name属性与全局属性id不是一回事。后者在HTML文档中多半用于CSS选择器。代码清单8展示的是一个设置了name属性和id属性的form元素。简单起见,例中这两个属性使用了同样的值。

代码清单8 使用form元素的name属性和id属性

<!DOCTYPE HTML>
<html>
    <head>
        <title>黄子涵</title>
        <meta name="作者" content="黄子涵"/>
        <meta name="描述" content="黄子涵是帅哥!"/>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <link rel="shortcut icon" href="favicon.ico" type="image/x-icon"/>
    </head>
    <body>
        <form name="黄子涵" id="黄子涵" method="post" action="http://120.77.46.246/form">
            <input name="fave"/>
            <input name="name"/>
            <button>黄子涵的按钮</button>
        </form>
    </body>
</html>

image

提交表单时其name属性值不会被发送给服务器,所以该属性的用处仅限于DOM中,不像input元素的同名属性那么重要。要是input元素不设置name属性,那么用户在其中输入的数据在提交表单时不会被发送给服务器。

在表单中添加说明标签

现在已经有了一个用来收集用户输入数据的表单,但是它用起来有点不方便。

这个表单明显缺乏给用户看的指示信息。谁会通过阅读HTML源代码来搞清每个文本框的用途呢?这个缺点可以用label元素弥补,该元素的用途是为表单中的每一个元素提供说明。下表概括了label元素。

label元素

image

代码清单9 使用label元素

<!DOCTYPE HTML>
<html>
    <head>
        <title>黄子涵</title>
        <meta name="作者" content="黄子涵"/>
        <meta name="描述" content="黄子涵是帅哥!"/>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <link rel="shortcut icon" href="favicon.ico" type="image/x-icon"/>
    </head>
    <body>
        <form method="post" action="http://120.77.46.246/form">
            <P><label for="fave">黄子涵是帅哥<input id="fave" name="fave"/></label></P>
            <p><label for="name">黄子涵是靓仔<input id="name" name="name"/></label></p>
            <button>黄子涵的按钮</button>
        </form>
    </body>
</html>

此例为每个input元素都配了一个label元素。注意,例中为input元素设置了id属性,并将相关label元素的for属性设置为这个id值。这样做即可将input元素和label元素关联起来,有助于屏幕阅读器和其他残障辅助技术对表单的处理。这些说明标签的显示结果如下图所示。

image

上面的代码清单把input元素作为label元素的内容放置在其中。这个不是强制性的要求,二者可以独立定义。在设计复杂表单的时候,label元素独立于input元素定义是很常见的事。

提示

此例在表单中添加了一些p元素,以便简单地设置一下表单的布局。这样做更方便读者观察在HTML文档中新添加的部分对呈现结果的影响。要想得到更美观的表单,需要用到CSS的表格特性。

自动聚焦到某个input元素

设计者可以让表单显示出来的时候即聚焦于某个input元素。这样用户就能直接在其中输入数据而不必先动手选择它。autofocus属性的用途就是指定这种元素,如代码清单10所示。

代码清单10 使用autofocus属性

<!DOCTYPE HTML>
<html>
    <head>
        <title>黄子涵</title>
        <meta name="作者" content="黄子涵"/>
        <meta name="描述" content="黄子涵是帅哥!"/>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <link rel="shortcut icon" href="favicon.ico" type="image/x-icon"/>
    </head>
    <body>
        <form method="post" action="http://120.77.46.246/form">
            <P>
                <label for="fave">黄子涵是帅哥<input autofocus id="fave" name="fave"/></label>
            </P>
            <p><label for="name">黄子涵是靓仔<input id="name" name="name"/></label></p>
            <button>黄子涵的按钮</button>
        </form>
    </body>
</html>

浏览器将这个页面一显示出来就会聚焦于第一个输入元素。下图显示了Chrome用以标示位于焦点上的那个元素的视觉信号。

image

autofocus属性只能用在一个input元素上。要是有几个元素都设置了这个属性,那么浏览器将会自动聚焦于其中的最后一个元素。

禁用单个input元素

如果不想让用户在某个input元素中输入数据,可以禁用它。这看似奇怪,其实不然。设计者也许想要为几个相关任务提供一致的用户界面,但是其中有些元素并非总是用得上。此外有时也需要根据用户的操作用JavaScript启用某些元素。这方面的一个常见例子是:在用户选择将货物发到账单地址之外的地址时,启用一组用来收集新地址信息的input元素。

要禁用input元素,需要设置其disabled属性,如代码清单11所示。

代码清单11 设置input元素的disabled属性

<!DOCTYPE HTML>
<html>
    <head>
        <title>黄子涵</title>
        <meta name="作者" content="黄子涵"/>
        <meta name="描述" content="黄子涵是帅哥!"/>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <link rel="shortcut icon" href="favicon.ico" type="image/x-icon"/>
    </head>
    <body>
        <form method="post" action="http://120.77.46.246/form">
            <P>
                <label for="fave">黄子涵是帅哥<input autofocus id="fave" name="fave"/></label>
            </P>
            <p><label for="name">黄子涵是靓仔<input disabled id="name" name="name"/></label></p>
            <button>黄子涵的按钮</button>
        </form>
    </body>
</html>

此例在收集用户姓名的那个input元素上设置了disabled属性。禁用后的input元素在Chrome中的样子如下图所示。其他浏览器为其使用的样式与此类似。

image

对表单元素编组

对于更复杂的表单,有时需要将一些元素组织在一起。为此可以使用fieldset元素。下表概括了这个元素。

fieldset 元素

image

代码清单12示范了fieldset元素的用法。该例添加了一些input元素,以演示如何将fieldset用于fonn中的一部分元素。

代码清单12 使用fieldset元素

<!DOCTYPE HTML>
<html>
    <head>
        <title>黄子涵</title>
        <meta name="作者" content="黄子涵"/>
        <meta name="描述" content="黄子涵是帅哥!"/>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <link rel="shortcut icon" href="favicon.ico" type="image/x-icon"/>
    </head>
    <body>
        <form method="post" action="http://120.77.46.246/form">
            <fieldset>
                <P><label for="fave">黄子涵是帅哥<input id="fave" name="fave"/></label></P>
                <p><label for="name">黄子涵是靓仔<input id="name" name="name"/></label></p>
            </fieldset>
            <fieldset>
                <p><label for="fave1">#黄子涵1:<input id="fave1" name="fave1"/></label></p>
                <p><label for="fave2">#黄子涵2:<input id="fave2" name="fave2"/></label></p>
                <p><label for="fave3">#黄子涵3:<input id="fave3" name="fave3"/></label></p>
            </fieldset>
            <button>黄子涵的按钮</button>
        </form>
    </body>
</html>

此例用一个fieldset元素将两个用来收集用户个人信息的input元素编为一组,又用另一个fieldset元素将三个用来让用户为其喜欢的水果投票的input元素编为一组。fieldset元素的习惯样式效果如下图所示。

image

为fieldset元素添加说明标签

上面的例子中已将input元素分别编组,但是未向用户提供相关说明。在每一个fieldset元素中添加一个legend元素即可弥补这个缺点,下表概括了这个元素。

legend元素

image

legend元素必须是fieldset元素的第一个子元素,如代码清单13所示。

代码清单13 使用legend元素

<!DOCTYPE HTML>
<html>
    <head>
        <title>黄子涵</title>
        <meta name="作者" content="黄子涵"/>
        <meta name="描述" content="黄子涵是帅哥!"/>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <link rel="shortcut icon" href="favicon.ico" type="image/x-icon"/>
    </head>
    <body>
        <form method="post" action="http://120.77.46.246/form">
            <fieldset>
                <legend>输入的相关的信息:</legend>
                <P><label for="fave">籍贯<input id="fave" name="fave"/></label></P>
                <p><label for="name">学校<input id="name" name="name"/></label></p>
            </fieldset>
            <fieldset>
                <legend>输入三个歌手的名字:</legend>
                <p><label for="fave1">#黄子涵1:<input id="fave1" name="fave1"/></label></p>
                <p><label for="fave2">#黄子涵2:<input id="fave2" name="fave2"/></label></p>
                <p><label for="fave3">#黄子涵3:<input id="fave3" name="fave3"/></label></p>
            </fieldset>
            <button>黄子涵的按钮</button>
        </form>
    </body>
</html>

legend元素在浏览器中的显示结果如下图所示。

image

用fieldset禁用整组input元素

通过设置fieldset元素的disabled属性,可以一次性地禁用多个input元素。此时fieldset元素中包含的所有input元素都会被禁用,如代码清单14所示。

代码清单14 用fieldset元素禁用input元素

<!DOCTYPE HTML>
<html>
    <head>
        <title>黄子涵</title>
        <meta name="作者" content="黄子涵"/>
        <meta name="描述" content="黄子涵是帅哥!"/>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <link rel="shortcut icon" href="favicon.ico" type="image/x-icon"/>
    </head>
    <body>
        <form method="post" action="http://120.77.46.246/form">
            <fieldset>
                <legend>输入的相关的信息:</legend>
                <P><label for="fave">籍贯<input id="fave" name="fave"/></label></P>
                <p><label for="name">学校<input id="name" name="name"/></label></p>
            </fieldset>
            <fieldset disabled>
                <legend>输入三个歌手的名字:</legend>
                <p><label for="fave1">#黄子涵1:<input id="fave1" name="fave1"/></label></p>
                <p><label for="fave2">#黄子涵2:<input id="fave2" name="fave2"/></label></p>
                <p><label for="fave3">#黄子涵3:<input id="fave3" name="fave3"/></label></p>
            </fieldset>
            <button>黄子涵的按钮</button>
        </form>
    </body>
</html>

这些input元素被禁用后的效果如下图所示。

image

使用button元素

button元素其实比它的外表给人的感觉更灵活。该元素有三种用法,这些不同的操作模式通过具有三种值的type属性设定,其说明见下表。

button元素的type属性的值

值 | 说 明
submit | 表示按钮的用途是提交表单
reset | 表示按钮的用途是重置表单
button | 表示按钮没有具体语义

下面我们来逐一说明上述三个属性值及其代表的功能。

用button元素提交表单

如果将button元素的type属性设置为submit,那么按下该按钮会提交包含它的表单。这是未设置type属性的button元素的默认行为。采用这种方法使用该元素时,它还有额外的一些属性可用,如下表所述。

type属性设置为submit时button元素的额外属性

属 性 | 说 明
form | 指定按钮关联的表单
formaction | 覆盖form元素的action属性,另行指定表单将要提交到的URL。
formenctype | 覆盖form元素的enctype属性,另行指定表单的编码方式
formmethod | 覆盖form元素的method属性
formtarget | 覆盖form元素的target属性
formnovalidate | 覆盖fom元素的novalidate属性,表明是否应执行客户端数据有效性检查。

这些属性主要是用来覆盖或补充form元素上的设置,指定表单提交的URL、使用的HTTP方法、编码方式、表单反馈信息的显示地点,以及控制客户端数据检查。它们是HTML5中新增的属性。代码清单15示范了这些元素的用法。

代码清单15 使用button元素的属性

<!DOCTYPE HTML>
<html>
    <head>
        <title>黄子涵</title>
        <meta name="作者" content="黄子涵"/>
        <meta name="描述" content="黄子涵是帅哥!"/>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <link rel="shortcut icon" href="favicon.ico" type="image/x-icon"/>
    </head>
    <body>
        <form method="post" action="http://120.77.46.246/form">
            <P>
                <label for="fave">黄子涵是帅哥<input autofocus id="fave" name="fave"/></label>
            </P>
            <p><label for="name">黄子涵是靓仔<input id="name" name="name"/></label></p>
            <button type="submit" formaction="http://120.77.46.246/form" formmethod="post">黄子涵的按钮</button>
        </form>
    </body>
</html>

此例未设置form元素的action和method属性,转而通过设置button元素的formaction和formmethod属性来达到同样的目的。

用button元素重置表单

如果将button元素的type属性设置为reset,那么按下按钮会将表单中所有input元素重置为初始状态。这样使用该元素时,没有额外的属性可用。代码清单16中的例子在HTML文档中添加了一个重置按钮。

代码清单16 用button元素重置表单

<!DOCTYPE HTML>
<html>
    <head>
        <title>黄子涵</title>
        <meta name="作者" content="黄子涵"/>
        <meta name="描述" content="黄子涵是帅哥!"/>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <link rel="shortcut icon" href="favicon.ico" type="image/x-icon"/>
    </head>
    <body>
        <form method="post" action="http://120.77.46.246/form">
            <P>
                <label for="fave">黄子涵是帅哥<input autofocus id="fave" name="fave"/></label>
            </P>
            <p><label for="name">黄子涵是靓仔<input id="name" name="name"/></label></p>
            <button type="submit">提交给黄子涵</button>
            <button type="reset">黄子涵把它重置了</button>
        </form>
    </body>
</html>

表单的重置效果如下图所示。

image

把button作为一般元素使用

如果将button元素的type属性设置为button,那么该button元素就仅仅是一个按钮。它没有特别的含义,在按下时也不会做任何事情。代码清单17的例子在HTML文档中添加了这样一个按钮。

代码清单17 使用一般性的button

<!DOCTYPE HTML>
<html>
    <head>
        <title>黄子涵</title>
        <meta name="作者" content="黄子涵"/>
        <meta name="描述" content="黄子涵是帅哥!"/>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <link rel="shortcut icon" href="favicon.ico" type="image/x-icon"/>
    </head>
    <body>
        <form method="post" action="http://120.77.46.246/form">
            <P>
                <label for="fave">黄子涵是帅哥<input autofocus id="fave" name="fave"/></label>
            </P>
            <p><label for="name">黄子涵是靓仔<input id="name" name="name"/></label></p>
            <button type="submit">提交给黄子涵</button>
            <button type="reset">黄子涵把它重置了</button>
            <button type="button">按下它<strong>不会</strong>做任何事</button>
        </form>
    </body>
</html>

这样使用该元素看起来似乎没有什么意义。但我们可以在按下按钮时可以用JavaScript执行一些操作。通过这种方法即可用button元素实现自定义的行为。

注意,此例对button元素包含的文字设置了一些格式。该元素中的文字可以用各种短语元素进行标记。该例中此处所作标记的效果如下图所示。

image

使用表单外的元素

在HTML4中,input、button和其他与表单相关的元素必须放在form元素中。在HTML5中,这条限制不复存在。现在可以将这类元素与文档中任何地方的表单挂钩。要将某个这类元素与并非其祖先元素的form元素挂钩,只消将其form属性设置为相关form元素的id属性值即可。代码清单18即为一例。

代码清单18 使用form属性

<!DOCTYPE HTML>
<html>
    <head>
        <title>黄子涵</title>
        <meta name="作者" content="黄子涵"/>
        <meta name="描述" content="黄子涵是帅哥!"/>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <link rel="shortcut icon" href="favicon.ico" type="image/x-icon"/>
    </head>
    <body>
        <form id="voteform" method="post" action="http://120.77.46.246/form">
            <P>
                <label for="fave">黄子涵是帅哥<input autofocus id="fave" name="fave"/></label>
            </P>
        </form>
        <p>
            <label for="name">黄子涵是靓仔<input form="voteform" id="name" name="name"/>
            </label>
        </p>
        
        <button form="voteform" type="submit">提交给黄子涵</button>
        <button form="voteform" type="reset">黄子涵把它重置了</button>       
    </body>
</html>

此例中只有一个input元素是那个form元素的后代元素。另一个input元素和两个button元素都位于form元素之外,但是它们都通过设置form属性与那个form元素关联在了一起。

image

posted @ 2021-10-02 19:17  黄子涵  阅读(185)  评论(0编辑  收藏  举报