HTML表单基础
学习目标
- 掌握HTML表单的基本结构和属性
- 学会使用各种表单元素
- 理解表单元素的属性配置
- 能够创建符合Web标准的表单
HTML表单基础结构
HTML表单由<form>标签包裹,包含各种输入元素。基本的表单结构如下:
<!DOCTYPE html>
<html>
<head>
<title>用户注册表单</title>
<meta charset="UTF-8">
</head>
<body>
<form action="process.php" method="post" enctype="multipart/form-data">
<!-- 表单元素将在这里 -->
<input type="submit" value="提交">
</form>
</body>
</html>
form标签的重要属性
1. action属性
指定表单数据提交的目标URL:
<!-- 提交到同一目录下的process.php文件 -->
<form action="process.php" method="post">
<!-- 提交到完整的URL -->
<form action="https://example.com/api/submit" method="post">
<!-- 提交到当前页面(常用于表单自处理) -->
<form action="" method="post">
<form action="<?php echo htmlspecialchars($_SERVER['PHP_SELF']); ?>" method="post">
2. method属性
指定HTTP请求方法:
<!-- GET方法:数据通过URL传递,有长度限制,不安全 -->
<form action="search.php" method="get">
<!-- POST方法:数据通过HTTP请求体传递,安全,适合敏感数据 -->
<form action="login.php" method="post">
3. enctype属性
指定表单数据的编码类型:
<!-- 默认值:application/x-www-form-urlencoded -->
<form action="submit.php" method="post" enctype="application/x-www-form-urlencoded">
<!-- 文件上传时必须使用:multipart/form-data -->
<form action="upload.php" method="post" enctype="multipart/form-data">
<!-- 纯文本编码,很少使用 -->
<form action="submit.php" method="post" enctype="text/plain">
4. 其他常用属性
<form action="process.php" method="post"
target="_blank" <!-- 在新窗口打开结果 -->
autocomplete="on" <!-- 启用自动完成 -->
novalidate> <!-- 禁用浏览器验证 -->
常用表单元素
1. 文本输入框
<!-- 单行文本输入 -->
<label for="username">用户名:</label>
<input type="text" id="username" name="username"
placeholder="请输入用户名"
maxlength="20"
required>
<!-- 密码输入框 -->
<label for="password">密码:</label>
<input type="password" id="password" name="password"
minlength="8"
required>
<!-- 邮箱输入框(HTML5验证) -->
<label for="email">邮箱:</label>
<input type="email" id="email" name="email"
placeholder="example@domain.com"
required>
<!-- 数字输入框 -->
<label for="age">年龄:</label>
<input type="number" id="age" name="age"
min="1" max="120" step="1">
<!-- 电话号码输入框 -->
<label for="phone">电话:</label>
<input type="tel" id="phone" name="phone"
pattern="[0-9]{11}"
placeholder="请输入11位手机号">
2. 文本域
<!-- 多行文本输入 -->
<label for="message">留言:</label>
<textarea id="message" name="message"
rows="5" cols="40"
maxlength="500"
placeholder="请输入您的留言..."
required></textarea>
3. 单选按钮
<fieldset>
<legend>性别:</legend>
<label>
<input type="radio" name="gender" value="male" required> 男
</label>
<label>
<input type="radio" name="gender" value="female"> 女
</label>
<label>
<input type="radio" name="gender" value="other"> 其他
</label>
</fieldset>
4. 复选框
<fieldset>
<legend>兴趣爱好:</legend>
<label>
<input type="checkbox" name="hobbies[]" value="reading"> 阅读
</label>
<label>
<input type="checkbox" name="hobbies[]" value="music"> 音乐
</label>
<label>
<input type="checkbox" name="hobbies[]" value="sports"> 运动
</label>
</fieldset>
5. 下拉选择框
<!-- 单选下拉框 -->
<label for="city">城市:</label>
<select id="city" name="city" required>
<option value="">请选择城市</option>
<option value="beijing">北京</option>
<option value="shanghai">上海</option>
<option value="guangzhou">广州</option>
<option value="shenzhen">深圳</option>
</select>
<!-- 多选下拉框 -->
<label for="skills">技能:</label>
<select id="skills" name="skills[]" multiple size="4">
<option value="php">PHP</option>
<option value="javascript">JavaScript</option>
<option value="python">Python</option>
<option value="java">Java</option>
<option value="css">CSS</option>
</select>
<!-- 分组下拉框 -->
<label for="province">省份:</label>
<select id="province" name="province">
<optgroup label="华北地区">
<option value="beijing">北京</option>
<option value="tianjin">天津</option>
</optgroup>
<optgroup label="华东地区">
<option value="shanghai">上海</option>
<option value="jiangsu">江苏</option>
</optgroup>
</select>
6. 文件上传
<!-- 单文件上传 -->
<label for="avatar">头像:</label>
<input type="file" id="avatar" name="avatar"
accept="image/*"
required>
<!-- 多文件上传 -->
<label for="documents">文档:</label>
<input type="file" id="documents" name="documents[]"
multiple
accept=".pdf,.doc,.docx">
<!-- 隐藏的文件上传(美观的界面) -->
<div class="file-upload">
<input type="file" id="fileInput" name="file" style="display: none;">
<button type="button" onclick="document.getElementById('fileInput').click()">
选择文件
</button>
<span id="fileName">未选择文件</span>
</div>
7. 按钮类型
<!-- 提交按钮 -->
<input type="submit" value="注册">
<button type="submit">注册</button>
<!-- 重置按钮 -->
<input type="reset" value="重置表单">
<button type="reset">重置表单</button>
<!-- 普通按钮 -->
<input type="button" value="普通按钮" onclick="alert('点击了按钮')">
<button type="button" onclick="alert('点击了按钮')">普通按钮</button>
<!-- 图像按钮 -->
<input type="image" src="submit.gif" alt="提交" width="100" height="30">
8. 隐藏字段
<!-- 用于传递不需要用户看到的数据 -->
<input type="hidden" name="user_id" value="<?php echo $user_id; ?>">
<input type="hidden" name="csrf_token" value="<?php echo generate_csrf_token(); ?>">
表单分组和标签
fieldset和legend
<form action="process.php" method="post">
<fieldset>
<legend>基本信息</legend>
<label for="name">姓名:</label>
<input type="text" id="name" name="name" required>
<label for="email">邮箱:</label>
<input type="email" id="email" name="email" required>
</fieldset>
<fieldset>
<legend>联系方式</legend>
<label for="phone">电话:</label>
<input type="tel" id="phone" name="phone">
<label for="address">地址:</label>
<input type="text" id="address" name="address">
</fieldset>
</form>
label标签的正确使用
<!-- 方法1:使用for属性关联 -->
<label for="username">用户名:</label>
<input type="text" id="username" name="username">
<!-- 方法2:包裹input元素 -->
<label>
密码:
<input type="password" name="password">
</label>
<!-- 方法3:隐藏label(仅用于屏幕阅读器) -->
<label for="search" class="sr-only">搜索:</label>
<input type="search" id="search" name="search" placeholder="搜索...">
HTML5新增特性
1. 新的输入类型
<!-- 日期选择器 -->
<label for="birthdate">出生日期:</label>
<input type="date" id="birthdate" name="birthdate">
<!-- 时间选择器 -->
<label for="time">预约时间:</label>
<input type="time" id="time" name="time">
<!-- 日期时间选择器 -->
<label for="datetime">会议时间:</label>
<input type="datetime-local" id="datetime" name="datetime">
<!-- 月份选择器 -->
<label for="month">月份:</label>
<input type="month" id="month" name="month">
<!-- 周选择器 -->
<label for="week">周:</label>
<input type="week" id="week" name="week">
<!-- 颜色选择器 -->
<label for="color">主题颜色:</label>
<input type="color" id="color" name="color" value="#ff0000">
<!-- URL输入 -->
<label for="website">个人网站:</label>
<input type="url" id="website" name="website" placeholder="https://">
<!-- 范围滑块 -->
<label for="volume">音量:</label>
<input type="range" id="volume" name="volume"
min="0" max="100" value="50" step="1">
<span id="volumeValue">50</span>
<!-- 搜索框 -->
<label for="search">搜索:</label>
<input type="search" id="search" name="search"
placeholder="输入搜索关键词..."
autocomplete="on">
2. 表单验证属性
<!-- 必填字段 -->
<input type="text" name="username" required>
<!-- 最小/最大长度 -->
<input type="text" name="username"
minlength="3" maxlength="20">
<!-- 最小/最大值 -->
<input type="number" name="age"
min="18" max="100">
<!-- 步长 -->
<input type="number" name="quantity"
min="0" max="10" step="0.5">
<!-- 正则表达式验证 -->
<input type="text" name="phone"
pattern="[0-9]{3}-[0-9]{4}-[0-9]{4}"
title="格式:xxx-xxxx-xxxx">
完整的用户注册表单示例
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>用户注册</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 600px;
margin: 0 auto;
padding: 20px;
}
.form-group {
margin-bottom: 15px;
}
label {
display: block;
margin-bottom: 5px;
font-weight: bold;
}
input, select, textarea {
width: 100%;
padding: 8px;
border: 1px solid #ddd;
border-radius: 4px;
box-sizing: border-box;
}
input[type="radio"], input[type="checkbox"] {
width: auto;
margin-right: 5px;
}
.error {
color: red;
font-size: 12px;
margin-top: 5px;
}
button {
background-color: #007bff;
color: white;
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
}
button:hover {
background-color: #0056b3;
}
</style>
</head>
<body>
<h1>用户注册</h1>
<form action="register.php" method="post" id="registrationForm">
<!-- 基本信息 -->
<fieldset>
<legend>基本信息</legend>
<div class="form-group">
<label for="username">用户名:</label>
<input type="text" id="username" name="username"
placeholder="请输入用户名"
minlength="3" maxlength="20"
required>
<div class="error" id="usernameError"></div>
</div>
<div class="form-group">
<label for="email">邮箱:</label>
<input type="email" id="email" name="email"
placeholder="example@domain.com"
required>
<div class="error" id="emailError"></div>
</div>
<div class="form-group">
<label for="password">密码:</label>
<input type="password" id="password" name="password"
minlength="8"
required>
<div class="error" id="passwordError"></div>
</div>
<div class="form-group">
<label for="confirmPassword">确认密码:</label>
<input type="password" id="confirmPassword" name="confirmPassword"
required>
<div class="error" id="confirmPasswordError"></div>
</div>
<div class="form-group">
<label>性别:</label>
<label>
<input type="radio" name="gender" value="male" required> 男
</label>
<label>
<input type="radio" name="gender" value="female"> 女
</label>
</div>
</fieldset>
<!-- 个人信息 -->
<fieldset>
<legend>个人信息</legend>
<div class="form-group">
<label for="birthdate">出生日期:</label>
<input type="date" id="birthdate" name="birthdate">
</div>
<div class="form-group">
<label for="phone">电话:</label>
<input type="tel" id="phone" name="phone"
pattern="[0-9]{11}"
placeholder="请输入11位手机号">
</div>
<div class="form-group">
<label for="address">地址:</label>
<input type="text" id="address" name="address">
</div>
<div class="form-group">
<label for="bio">个人简介:</label>
<textarea id="bio" name="bio"
rows="4"
maxlength="200"
placeholder="简单介绍一下自己..."></textarea>
</div>
</fieldset>
<!-- 兴趣爱好 -->
<fieldset>
<legend>兴趣爱好</legend>
<div class="form-group">
<label>请选择您的爱好:</label>
<div>
<label>
<input type="checkbox" name="hobbies[]" value="reading"> 阅读
</label>
<label>
<input type="checkbox" name="hobbies[]" value="music"> 音乐
</label>
<label>
<input type="checkbox" name="hobbies[]" value="sports"> 运动
</label>
<label>
<input type="checkbox" name="hobbies[]" value="travel"> 旅行
</label>
<label>
<input type="checkbox" name="hobbies[]" value="photography"> 摄影
</label>
</div>
</div>
</fieldset>
<!-- 头像上传 -->
<fieldset>
<legend>头像上传</legend>
<div class="form-group">
<label for="avatar">选择头像:</label>
<input type="file" id="avatar" name="avatar"
accept="image/*">
</div>
</fieldset>
<!-- 服务条款 -->
<div class="form-group">
<label>
<input type="checkbox" name="terms" required>
我已阅读并同意<a href="terms.html">服务条款</a>
</label>
</div>
<!-- 提交按钮 -->
<div class="form-group">
<button type="submit">注册</button>
<button type="reset">重置</button>
</div>
</form>
<script>
// 简单的客户端验证
document.getElementById('registrationForm').addEventListener('submit', function(e) {
let isValid = true;
// 验证密码匹配
const password = document.getElementById('password').value;
const confirmPassword = document.getElementById('confirmPassword').value;
const confirmError = document.getElementById('confirmPasswordError');
if (password !== confirmPassword) {
confirmError.textContent = '密码不匹配';
isValid = false;
} else {
confirmError.textContent = '';
}
if (!isValid) {
e.preventDefault();
}
});
</script>
</body>
</html>
最佳实践
- 使用语义化HTML:正确使用label、fieldset等标签
- 提供良好的用户体验:清晰的标签、合理的布局、即时反馈
- 移动端友好:使用响应式设计和适当的输入类型
- 安全性考虑:使用适当的方法和编码类型
- 无障碍访问:确保表单对残障用户友好
总结
HTML表单是Web应用程序中用户交互的基础。掌握表单的创建和各种输入元素的使用,是开发高质量Web应用的前提。在下一章中,我们将学习如何处理这些表单数据,包括GET和POST方法的使用。