从用户输入到数据存储 | 课型:实习课 | 建议课时:3节
姓名/手机/邮箱验证+localStorage自动保存草稿+提交成功反馈。
新窗口运行 下载源码<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>竞赛报名表</title>
<style>
body { font-family: "Microsoft YaHei", sans-serif; background: #f2f6f8; margin: 0;
display: flex; justify-content: center; padding: 30px 16px; }
form { background: #fff; padding: 28px; border-radius: 14px; width: 420px;
box-shadow: 0 6px 24px rgba(18,58,82,.1); }
h1 { font-size: 20px; color: #123a52; margin: 0 0 18px; }
label { display: block; margin: 14px 0 6px; font-size: 14px; }
input, select { width: 100%; padding: 10px; border: 2px solid #d7e3ea; border-radius: 8px;
font-size: 15px; box-sizing: border-box; }
input:focus { border-color: #0f8c7f; outline: none; }
.err { color: #c05a1e; font-size: 13px; min-height: 18px; margin-top: 4px; }
button { margin-top: 18px; width: 100%; padding: 12px; border: none; border-radius: 8px;
background: #0f8c7f; color: #fff; font-size: 16px; cursor: pointer; }
#ok { display: none; margin-top: 14px; background: #e7f7f4; color: #0f8c7f;
padding: 10px; border-radius: 8px; text-align: center; }
</style>
</head>
<body>
<form id="reg" novalidate>
<h1>第47届世赛选拔赛报名表</h1>
<label>姓名</label><input id="name" placeholder="请输入真实姓名"><div class="err" id="e-name"></div>
<label>手机号</label><input id="phone" placeholder="11位手机号"><div class="err" id="e-phone"></div>
<label>邮箱</label><input id="email" placeholder="name@example.com"><div class="err" id="e-email"></div>
<label>参赛模块</label>
<select id="module"><option value="">请选择</option><option>模块A 网页元素开发</option><option>模块B 页面设计</option></select>
<div class="err" id="e-module"></div>
<button type="submit">提交报名</button>
<div id="ok">✅ 报名成功!数据已保存到localStorage</div>
</form>
<script>
const $ = id => document.getElementById(id);
const rules = {
name: [v => v.trim().length >= 2, '姓名至少2个字符'],
phone: [v => /^1\d{10}$/.test(v), '手机号应为1开头的11位数字'],
email: [v => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(v), '邮箱格式不正确'],
module:[v => v !== '', '请选择参赛模块']
};
// 草稿自动保存
['name','phone','email','module'].forEach(id => {
$(id).value = localStorage.getItem('reg-' + id) || '';
$(id).addEventListener('input', () => localStorage.setItem('reg-' + id, $(id).value));
});
$('reg').addEventListener('submit', e => {
e.preventDefault();
let pass = true;
for (const id in rules) {
const [test, msg] = rules[id];
const ok = test($(id).value);
$('e-' + id).textContent = ok ? '' : '⚠ ' + msg;
if (!ok) pass = false;
}
if (pass) { $('ok').style.display = 'block'; console.log('提交数据:', JSON.stringify({
name: $('name').value, phone: $('phone').value, email: $('email').value, module: $('module').value })); }
});
</script>
</body>
</html>任务目标:独立完成带验证、存储的竞赛报名表
| 任务内容与评分 |
|---|
| 任务1:搭建四字段表单结构(15分) |
| 任务2:编写手机号与邮箱正则验证(25分) |
| 任务3:错误提示逐字段友好显示(20分) |
| 任务4:localStorage草稿自动保存(20分) |
| 任务5:用fetch将数据POST到测试接口(20分) |