09 篇把顶部导航栏做好了。页面接下来要干两件事:让用户填东西(搜索条件、注册信息)和把一堆数据摆整齐(员工列表)——前者靠表单标签,后者靠表格标签。这一篇把这两类标签一次讲完。
案例背景:第二个、第三个区域
Tlias 页面原型里,导航栏下面就是这两个区域:
图:导航栏下面是"搜索表单区域"(一排查询条件 + 查询/清空按钮),再下面是"表格数据展示区域"(姓名/性别/头像/职位/入职日期…)
对应的提示词分别是:
AI 提示词
再继续帮我生成第二个部分:2. 搜索表单区域…
再继续帮我生成第三个部分:3. 表格数据展示区域…
表单:网页的数据采集器
表单:在网页中主要负责数据采集功能,如注册、登录等数据采集。
生活里到处都是表单——注册页面要填用户名/手机号/密码/验证码,实名认证要填证件信息、选性别、选证件类型,登录框要填账号密码:
图:一个典型表单:若干个输入框 + 一个提交按钮(每个框里还有灰字的提示语)
图:复杂一点的表单——单选框(性别)、下拉列表(证件类型)、文本域(其它信息描述)都上场了
表单由三部分组成:
| 组成 | 标签 | 说明 |
|---|---|---|
| 表单标签 | <form> | 把整张表单圈起来,管"这批数据提交到哪、怎么提交" |
| 表单项 | <input> | 不同类型的 input 元素,通过 type 属性控制输入形式(text/password/…) |
<select> | 定义下拉列表 | |
<textarea> | 定义文本域(多行输入框) |
先看最小的一个表单(课程文件 12. 表单标签.html):
<form action="/save" method="post">
姓名: <input type="text" name="name">
年龄: <input type="text" name="age">
<input type="submit" value="提交">
</form>IMPORTANT
表单项要想能够采集数据,必须设置 name 属性,它表示这个表单项的"名字"。后端收到的是 name=值 这样成对的数据——没写 name 的输入框,用户填了也提交不上去。
<form> 的两个属性:action 与 method
| 属性 | 作用 |
|---|---|
action | 规定当提交表单时向何处发送表单数据,值是 URL(表单数据提交的 url 地址) |
method | 规定用于发送表单数据的方式,取值 GET、POST |
method 的两种方式差别很大:
| 对比项 | GET | POST |
|---|---|---|
| 数据放在哪 | 拼在 url 后面,如 /save?name=java | 在请求体(消息体)中携带 |
| 大小限制 | 有大小限制(浏览器对 url 长度有限制),不适合提交大数据量的表单 | 没有大小限制 |
| 安全性 | 不安全:url 谁都能看到,含隐私数据不推荐 | 安全:数据在请求体里 |
| 典型用途 | 查询、搜索这类"取数据"的请求 | 提交注册/登录/保存这类"送数据"的请求 |
<!-- 数据会以 /save?name=Tom&age=18 的形式发出去,隐私数据一眼可见 -->
<form action="/save" method="get">
姓名: <input type="text" name="name">
<input type="submit" value="提交">
</form>
<!-- 数据放在请求体里发出去,url 上看不到 -->
<form action="/save" method="post">
姓名: <input type="text" name="name">
<input type="submit" value="提交">
</form>TIP
method 不写时默认是 GET。课程案例里两个表单一个都没省:搜索表单用 method="post"、注册这类都是 post。后面学后端时你会再见到这两种请求方式——这里记住"数据放哪儿"和"有没有大小限制"这两个差别就够了。
表单项一:<input> 的 type 取值
<input> 是表单项里出场最多的一个,通过 type 属性控制输入形式:
| type 取值 | 描述 | 页面上长什么样 |
|---|---|---|
text | 默认值,定义单行的输入字段 | 一个可以打字的方框(如 张无忌) |
password | 定义密码字段 | 输入内容显示成圆点 ······ |
radio | 定义单选按钮 | ○ 男 ○ 女(一组里只能选一个) |
checkbox | 定义复选框 | □ Java □ Game(可以选多个) |
file | 定义文件上传按钮 | 一个"选择文件"按钮 + "未选择任何文件" |
date / time / datetime-local | 定义日期 / 时间 / 日期时间 | 带日历/时钟图标的日期时间选择器 |
hidden | 定义隐藏域 | 页面上看不见,但数据照样提交 |
submit / reset / button | 定义提交按钮 / 重置按钮 / 可点击按钮 | 三个小按钮:提交、重置、按钮 |
图:PPT 原表——每一行右边都直接给出了该类型的实际外观(文字、圆点、单选框、复选框、文件上传、日期时间、按钮)
课程文件 13. 表单项标签.html 把常用的类型挨个写了一遍:
<!-- value: 表单项提交的值 -->
<form action="/save" method="post">
姓名: <input type="text" name="name"> <br><br>
密码: <input type="password" name="password"> <br><br>
性别: <input type="radio" name="gender" value="1"> 男
<label><input type="radio" name="gender" value="2"> 女 </label> <br><br>
爱好: <label><input type="checkbox" name="hobby" value="java"> java </label>
<label><input type="checkbox" name="hobby" value="game"> game </label>
<label><input type="checkbox" name="hobby" value="sing"> sing </label> <br><br>
图像: <input type="file" name="image"> <br><br>
生日: <input type="date" name="birthday"> <br><br>
时间: <input type="time" name="time"> <br><br>
日期时间: <input type="datetime-local" name="datetime"> <br><br>
学历: <select name="degree">
<option value="">----------- 请选择 -----------</option>
<option value="1">大专</option>
<option value="2">本科</option>
<option value="3">硕士</option>
<option value="4">博士</option>
</select> <br><br>
描述: <textarea name="description" cols="30" rows="10"></textarea> <br><br>
<input type="hidden" name="id" value="1">
<!-- 表单常见按钮 -->
<input type="button" value="按钮">
<input type="reset" value="重置">
<input type="submit" value="提交">
<br>
</form>这段代码里有几个必须掌握的细节:
name相同的单选框是一组:两个type="radio"都写了name="gender",所以它们互斥(选了男就选不了女)。如果两份 name 不一样,就变成两组单选框、能同时选中——这是单选按钮最常见的错。value是"提交出去的值":页面上显示的是"男",提交给服务器的却是gender=1。复选框同理:勾了 Java 提交的是hobby=java。- 下拉列表的
<option>也靠value提交,第一个value=""的"请选择"是占位项(默认选中一个空的,逼用户自己选)。 hidden隐藏域:页面看不见,但id=1会跟表单一起提交——用来悄悄带上一个不需要用户填、但后端要用的值(比如"当前正在编辑的是哪条数据")。- 三种按钮的差别:
submit提交表单、reset把表单里的内容恢复成初始值、button只是个可点击按钮(点了不干任何事,行为要靠 JavaScript)。
补充:`<label>` 是"标签",在课程代码里配合表单项使用。`<label><input type="checkbox" …> java </label>` 这种包起来的写法,可以让**点文字也能勾选**;另一种写法是 `<label for="name">姓名:</label>` + `<input id="name">`(`for` 的值等于输入框的 `id`)。PPT 没有展开讲,但案例代码里到处都在用。
表单项二、三:<select> 与 <textarea>
图:左边是下拉列表(点开后有初中/高中/大专/本科/硕士/博士若干选项),右边是文本域(一个可以输入多行的大方框)
<select>:定义下拉列表,里面的<option>定义列表项(每一项。<select>要有name,<option>要有value):
<select name="degree">
<option value="">----------- 请选择 -----------</option>
<option value="1">大专</option>
<option value="2">本科</option>
</select><textarea>:定义文本域(多行输入框),用cols(列数/宽度)和rows(行数/高度)控制大小:
<textarea name="description" cols="30" rows="10"></textarea>| 标签 | 作用 | 关键属性 |
|---|---|---|
<select> / <option> | 下拉列表 / 列表项 | name(列表名)、value(该项提交的值) |
<textarea> | 文本域(多行文本) | name、cols、rows |
表格标签
第三个区域要把员工数据一行行列出来,用的是表格标签:
| 标签 | 描述 |
|---|---|
<table> | 定义表格整体 |
<thead> | 用于定义表格头部(可选) |
<tbody> | 定义表格中的主体部分(可选) |
<tr> | 表格的行,可以包裹多个 <td> |
<td> | 表格单元格(普通),可以包裹内容;如果是表头单元格,可以替换为 <th> |
图:PPT 原表——五个表格标签各自的描述(<table> 表格整体、<thead> 表头可选、<tbody> 主体可选、<tr> 行、<td> 单元格)
图:一张表格被分成两截——上面那一行(表头)属于 <thead>,下面所有数据行属于 <tbody>
结构关系一句话记住:<table> 里放 <thead> 和 <tbody>;它们里面放 <tr>(行);<tr> 里面放 <td>(单元格)或 <th>(表头单元格)。
<table>
<!-- 表头:thead 里的一行,单元格用 th -->
<thead>
<tr>
<th>姓名</th>
<th>职位</th>
<th>入职日期</th>
</tr>
</thead>
<!-- 表格主体:tbody 里可以有多行 -->
<tbody>
<tr>
<td>令狐冲</td>
<td>讲师</td>
<td>2021-06-15</td>
</tr>
<tr>
<td>任盈盈</td>
<td>咨询师</td>
<td>2021-07-20</td>
</tr>
</tbody>
</table>课程文件 15. Tlias案例-表格数据展示区域.html 就是按这个结构写的(单元格里还放了头像图片和"编辑/删除"按钮):
<table>
<!-- 表头 -->
<thead>
<tr>
<th>姓名</th>
<th>性别</th>
<th>头像</th>
<th>职位</th>
<th>入职日期</th>
<th>最后操作时间</th>
<th>操作</th>
</tr>
</thead>
<!-- 表格主体内容 -->
<tbody>
<tr>
<td>令狐冲</td>
<td>男</td>
<td><img class="avatar" src="https://web-framework.oss-cn-hangzhou.aliyuncs.com/2023/1.jpg" alt="令狐冲"></td>
<td>讲师</td>
<td>2021-06-15</td>
<td>2024-09-16 15:30</td>
<td class="action-buttons">
<button type="button">编辑</button>
<button type="button">删除</button>
</td>
</tr>
<!-- 后面还有若干行 -->
</tbody>
</table>配套的表格样式(同一份课程文件里的 CSS,PPT 没展开,先知道"表格默认很丑、要加这些"就行):
table {
width: 100%;
border-collapse: collapse; /* 相邻单元格的边框合并成一条,表格才不会像网格线 */
}
th, td {
border: 1px solid #ddd; /* 单元格边框 */
padding: 8px; /* 单元格内边距 */
text-align: center; /* 内容居中 */
}
th {
background-color: #f2f2f2; /* 表头灰底 */
font-weight: bold;
}WARNING
<table> 里直接写 <tr> 也是合法的(浏览器会自动补一层 <tbody>),但课程案例的写法是把 <thead> 和 <tbody> 都写全——语义清楚,后面用 CSS/JS 分别控制表头和数据行也方便。另外别把 <td> 和 <th> 写混:表头单元格用 <th>(默认加粗居中),数据单元格用 <td>。
小结
| 类别 | 标签 / 属性 | 说明 |
|---|---|---|
| 表单 | <form> | 定义表单(属性:action 提交地址、method 提交方式 GET/POST) |
<input type="text/button/…"> | 表单项(文本输入框、按钮等),type 控制形式、name 决定能否被提交、value 是提交的值 | |
<select> / <option> | 表单项(下拉列表 / 列表项) | |
<textarea> | 表单项(文本域,多行输入) | |
| 表格 | <table>、<thead>、<tbody> | 表格、表头、表格主体 |
<tr> / <th>、<td> | 行 / 表头单元格、普通单元格 | |
| 注意 | 表单项必须有 name | 没有 name 的表单项采集不到数据 |
相关
练习题
一、知识回顾(读完直接做下面的实践题)
- 表单在网页中主要负责数据采集功能(注册、登录等);表单标签是
<form>,表单项包括不同类型的 input 元素、下拉列表、文本域 - 表单项三种标签:
<input>(通过type属性控制输入形式)、<select>(下拉列表,里面的<option>定义列表项)、<textarea>(文本域,多行输入,用cols/rows控制大小) action:规定当提交表单时向何处发送表单数据(URL);method:规定用于发送表单数据的方式(GET、POST,不写默认 GET)- GET:表单数据拼接在 url 后面(如
/save?name=java),大小有限制、含隐私数据不安全;POST:表单数据在请求体中携带,大小没有限制、安全 - 注意:表单项必须有
name属性才可以提交——没有name的输入框,用户填了也采集不到 <input>的type取值:text(默认,单行输入)、password(密码)、radio(单选)、checkbox(复选)、file(文件上传)、date/time/datetime-local(日期/时间/日期时间)、hidden(隐藏域)、submit/reset/button(提交/重置/可点击按钮)value是表单项提交的值:页面上写"男",提交出去的是gender=1;一组单选按钮必须共用同一个name才会互斥(只能选一个)<textarea>用cols(列/宽)和rows(行/高) 控制输入框大小;<select>的<option value="">常用来做"请选择"占位项- 表格标签结构:
<table>(表格整体)里放<thead>(表头,可选)和<tbody>(主体,可选);它们里面是<tr>(行);行里放<td>(普通单元格)或<th>(表头单元格) - 表格样式要点:
border-collapse: collapse让相邻单元格边框合并、th,td设border与padding(案例里表格宽度width: 100%)
二、裸写题
- 里面有一个输入框用来填姓名,还有一个下拉列表可以选择性别(男/女,第一项是"请选择")
- 还要一个查询按钮和清空按钮
- 整个表单提交到
/search,并且用 POST 方式提交(填进去的内容不能出现在 url 上) - 两个表单项都要能被提交出去 (练习文件
test_10_搜索表单.html里有写作区,页面骨架已备好。)
- 提示(先自己想,实在想不出再点开)
一级 · 思路:三步——① 用表单标签把这一组控件圈起来并指定"提交到哪、怎么提交";② 写单行输入框和下拉列表;③ 写按钮 二级 · 方法:
<form action="/search" method="post">;输入框<input type="text" name="name">;下拉<select name="gender"><option value="">…</option><option value="1">男</option>…</select>;按钮<button type="submit">查询</button>/<button type="reset">清空</button>三级 · 骨架:<form action="____" method="____">…<input type="____" name="____">…<select name="____"><option value="">…</option></select>…<button type="____">查询</button>- 参考答案(做完再点开)
html<form action="/search" method="post"> <label for="name">姓名:</label> <input type="text" id="name" name="name" placeholder="请输入姓名"> <label for="gender">性别:</label> <select id="gender" name="gender"> <option value=""></option> <option value="1">男</option> <option value="2">女</option> </select> <button type="submit">查询</button> <button type="reset">清空</button> </form>对照课程
14. Tlias案例-搜索表单区域.html。三个检查点:method="post"(不能用默认的 get,否则姓名会出现在 url 上);两个控件都写了name;按钮写了type="submit"才能触发表单提交(reset负责恢复初始值)。- 性别:两个单选项(男 / 女),只能选一个;选男提交
gender=1、选女提交gender=2 - 爱好:三个复选项(java / game / sing),可以多选,提交的名字统一叫
hobby - 生日:一个日期选择控件,提交的名字叫
birthday(练习文件test_10_登记表单项.html里有写作区。)
- 提示(先自己想,实在想不出再点开)
一级 · 思路:单选用一种输入类型、复选用另一种;"只能选一个"这件事是由同一个 name 保证的,不是靠属性开关 二级 · 方法:
type="radio"(一组共用同一个name="gender",每项用value区分);type="checkbox"(多项共用name="hobby");日期用type="date"三级 · 骨架:<input type="____" name="gender" value="1"> 男/<input type="____" name="hobby" value="java"> java/<input type="____" name="birthday">- 参考答案(做完再点开)
html<form action="/save" method="post"> 性别: <input type="radio" name="gender" value="1"> 男 <label><input type="radio" name="gender" value="2"> 女 </label> <br><br> 爱好: <label><input type="checkbox" name="hobby" value="java"> java </label> <label><input type="checkbox" name="hobby" value="game"> game </label> <label><input type="checkbox" name="hobby" value="sing"> sing </label> <br><br> 生日: <input type="date" name="birthday"> </form>对照课程
13. 表单项标签.html。要点:单选框两个 name 必须一样(gender)才会互斥,靠value区分提交值(1 / 2);复选框三项 name 也一样(hobby),可以同时勾多个,提交出去是hobby=java&hobby=game这种多值形式;每个<label>把输入框和文字包起来,点文字也能选中。- 性别:两个单选项(男 / 女),只能选一个;选男提交
- 一个职位下拉列表,提交名字叫
position,选项有:班主任、讲师、学工主管、教研主管、咨询师,第一项是空的"请选择" - 一个描述文本域,提交名字叫
description,宽 30 列、高 10 行 (练习文件test_10_下拉与文本域.html里有写作区。)
- 提示(先自己想,实在想不出再点开)
一级 · 思路:下拉用一个外层标签把若干"选项"装起来;多行输入用另外那个标签,尺寸靠两个属性控制 二级 · 方法:
<select name="position">里放多个<option value="1">班主任</option>;文本域<textarea name="description" cols="30" rows="10"></textarea>三级 · 骨架:<select name="____"><option value="">----------- 请选择 -----------</option>…</select>/<textarea name="____" cols="____" rows="____"></textarea>- 参考答案(做完再点开)
html职位: <select name="position"> <option value="">----------- 请选择 -----------</option> <option value="1">班主任</option> <option value="2">讲师</option> <option value="3">学工主管</option> <option value="4">教研主管</option> <option value="5">咨询师</option> </select> <br><br> 描述: <textarea name="description" cols="30" rows="10"></textarea>对照课程
13. 表单项标签.html(学历下拉)和14. Tlias案例-搜索表单区域.html(职位下拉)。<option>的value才是提交的值;不写value时会默认提交标签里的文字,但实际项目里都是显式写value(一般是数据库里的编号)。- 一个职位下拉列表,提交名字叫
- 表单里有一个文件上传控件(提交名字
image) - 有一个隐藏的表单项,把
id=1一起提交(用户看不到它) - 有一个重置按钮,点了能把表单内容恢复到初始状态 (练习文件
test_10_文件与隐藏域.html里有写作区。)
- 提示(先自己想,实在想不出再点开)
一级 · 思路:文件上传、看不见的项、重置按钮——都是同一个标签换一种
type二级 · 方法:<input type="file" name="image">;隐藏域<input type="hidden" name="id" value="1">;重置按钮<input type="reset" value="重置">三级 · 骨架:<input type="____" name="image">/<input type="____" name="id" value="____">/<input type="____" value="重置">- 参考答案(做完再点开)
html<form action="/save" method="post"> 图像: <input type="file" name="image"> <br><br> <!-- 隐藏域:页面看不见,但值会跟着表单提交 --> <input type="hidden" name="id" value="1"> <input type="reset" value="重置"> <input type="submit" value="提交"> </form>对照课程
13. 表单项标签.html。隐藏域虽然看不见,但照样要有name和value(name是它的名字、value是它提交的值);type="reset"只清空这个表单内部的内容,不会刷新页面。- 表单里有一个文件上传控件(提交名字
三、综合题
- 表单:用表单标签把搜索区圈起来,提交到
/search、用 POST 方式 - 姓名:加一个单行输入框(名字
name),配一个"姓名:"的说明文字 - 性别与职位:两个下拉列表(名字分别
gender、position),性别选项为 空/男/女,职位选项为 空/班主任/讲师/学工主管/教研主管/咨询师 - 按钮:加"查询"和"清空"两个按钮
- 表格:表格整体 + 表头行(姓名、性别、职位、入职日期)用表头单元格
- 表格数据:主体部分加两行数据(令狐冲/男/讲师/2021-06-15、任盈盈/女/咨询师/2021-07-20)
- 自查:数一数表单里一共有几个
name?表格里表头用了<th>、数据用了<td>吗?
- 提示(先自己想,实在想不出再点开)
一级 · 思路:第 1~4 步是"表单 + 几个表单项";第 5~6 步是"表格整体 → 头部 → 主体",一层套一层 二级 · 方法:
<form action="/search" method="post">;<input type="text" name="name">;两个<select>里放<option>;<button type="submit">查询</button>/<button type="reset">清空</button>;表格<table><thead><tr><th>…+<tbody><tr><td>…三级 · 骨架:<form action="____" method="____">…<table><thead><tr><th>____</th></tr></thead><tbody><tr><td>____</td></tr></tbody></table>- 参考答案(做完再点开)
html<!-- 搜索表单区域 --> <form action="/search" method="post"> <label for="name">姓名:</label> <input type="text" id="name" name="name" placeholder="请输入姓名"> <label for="gender">性别:</label> <select id="gender" name="gender"> <option value=""></option> <option value="1">男</option> <option value="2">女</option> </select> <label for="position">职位:</label> <select id="position" name="position"> <option value=""></option> <option value="1">班主任</option> <option value="2">讲师</option> <option value="3">学工主管</option> <option value="4">教研主管</option> <option value="5">咨询师</option> </select> <button type="submit">查询</button> <button type="reset">清空</button> </form> <!-- 表格展示区 --> <table> <!-- 表头 --> <thead> <tr> <th>姓名</th> <th>性别</th> <th>职位</th> <th>入职日期</th> </tr> </thead> <!-- 表格主体内容 --> <tbody> <tr> <td>令狐冲</td> <td>男</td> <td>讲师</td> <td>2021-06-15</td> </tr> <tr> <td>任盈盈</td> <td>女</td> <td>咨询师</td> <td>2021-07-20</td> </tr> </tbody> </table>第 7 步的答案:表单里有 3 个
name(name、gender、position)——按钮不需要name(它们不是"数据",是操作);表格里表头四个单元格用的是<th>、数据行用的是<td>。对照课程14. Tlias案例-搜索表单区域.html与15. Tlias案例-表格数据展示区域.html,课程版本还多加了头像列、操作列和表格样式,结构是一样的。- 表单:用表单标签把搜索区圈起来,提交到
