学生信息管理案例
学生信息管理案例
实际效果:
一、HTML结构搭建
首先需要创建页面的基础结构,包括表单(用于输入学生信息)和表格(用于展示学生信息)。
- 表单区域:包含姓名、年龄、性别、薪资、就业城市,以及"录入"按钮。
- 表格区域:包含thead学号、姓名、年龄等字段和tbody用于动态展示数)。
<!-- 表单部分 -->
<form class="info" autocomplete="off">姓名:<input type="text" class="uname" name="uname" />年龄:<input type="text" class="age" name="age" />性别: <select name="gender" class="gender">...</select>薪资:<input type="text" class="salary" name="salary" />就业城市:<select name="city" class="city">...</select><button class="add">录入</button>
</form><!-- 表格部分 -->
<table><thead><tr><th>学号</th><th>姓名</th><th>年龄</th><th>性别</th><th>薪资</th><th>就业城市</th><th>操作</th></tr></thead><tbody></tbody>
</table>
二、数据存储设计
学生信息需要临时存储在客户端,这里使用对象数组arr
存储所有学生对象,每个对象包含学生的详细信息(学号、姓名、年龄等)。
// 定义数组存储学生数据,每个元素是一个学生对象
const arr = [];
- *数组按顺序存储多个学生对象,方便后续遍历渲染和删除操作。
- 学生对象结构:包含stui、uname、age。
三、表单提交与数据验证
表单提交是核心交互之一,需要实现"收集输入数据→验证数据→存储数据"的流程。
步骤1:阻止表单默认提交行为
表单默认提交会导致页面刷新,需通过e.preventDefault()
阻止:
//选取表单,添加提交事件
const info = document.querySelector('.info');
info.addEventListener('submit', function (e) {e.preventDefault(); // 阻止默认提交行为
});
步骤2:表单验证
提交前需检查所有输入项,确保没有空值(去除首尾空格后仍为空):
// 获取所有带name属性的输入项
const items = document.querySelectorAll('[name]');// 遍历所有输入项验证
for (let i = 0; i < items.length; i++) {// 将值转为字符串并去除空格,判断是否为空// 验证输入内容,避免空内容// trim方法是字符串中的,并且.value也不一定是字符串类型,所以需要转化为字符串类型if (String(items[i].value).trim() === '') {alert('请完整填写信息');//this是表单this.reset(); // 清空表单,避免残留无效数据return; // 终止后续逻辑}
}
使用String()
确保值为字符串类型,trim()
去除首尾空格,避免用户输入纯空格
四、数据存储与表格渲染
验证通过后,需将数据存入数组,并动态生成表格行展示。
步骤1:存储数据到数组
创建学生对象,包含学号(基于数组长度生成,确保唯一)和各输入项的值,然后存入数组:
const obj = {stuId: arr.length + 1, // 学号uname: uname.value, // 姓名age: age.value, // 年龄gender: gender.value, // 性别salary: salary.value, // 薪资city: city.value // 就业城市
};
arr.push(obj); // 存入数组
this.reset();
步骤2:动态渲染表格数据
定义render()
函数,遍历数组,为每个学生对象生成表格行(tr
),并添加到tbody
中:
const tbody = document.querySelector('tbody');function render() {tbody.innerHTML = ''; // 渲染前先清空tbody,避免重复渲染// 遍历数组,生成表格行for (let i = 0; i < arr.length; i++) {const tr = document.createElement('tr');// 给tr添加data-id属性,存储索引(用于删除操作)tr.dataset.id = i;// 填充表格内容tr.innerHTML = `<td>${arr[i].stuId}</td><td>${arr[i].uname}</td><td>${arr[i].age}</td><td>${arr[i].gender}</td><td>${arr[i].salary}</td><td>${arr[i].city}</td><td><a href="javascript:">删除</a></td>`;tbody.appendChild(tr); // 添加到表格}
}
五、删除功能实现
删除功能需通过事件委托实现(因删除按钮是动态生成的,静态绑定事件会失效)。
步骤:通过事件委托处理删除点击
在tbody
上绑定点击事件,判断点击目标是否为"删除"链接,然后通过data-id
获取索引,从数组中删除对应数据并重新渲染:
完整代码
tbody.addEventListener('click', function (e) {// 判断点击的是删除链接(a标签)if (e.target.tagName === 'A') {// 获取tr的data-id(即数组索引)//a的父亲的父亲也就是tbodyconst index = e.target.parentNode.parentNode.dataset.id;arr.splice(index, 1);// 重新渲染表格render();}
});
-利用事件冒泡,将事件绑定在父元素(tbody
)上,动态生成的子元素(a
标签)触发事件后,父元素可捕获并处理,避免重复绑定。
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta http-equiv="X-UA-Compatible" content="ie=edge" /><title>学生信息管理</title><link rel="stylesheet" href="css/index.css" />
</head><body><h1>新增学员</h1><form class="info" autocomplete="off">姓名:<input type="text" class="uname" name="uname" />年龄:<input type="text" class="age" name="age" />性别:<select name="gender" class="gender"><option value="男">男</option><option value="女">女</option></select>薪资:<input type="text" class="salary" name="salary" />就业城市:<select name="city" class="city"><option value="北京">北京</option><option value="上海">上海</option><option value="广州">广州</option><option value="深圳">深圳</option><option value="曹县">曹县</option></select><button class="add">录入</button></form><h1>就业榜</h1><table><thead><tr><th>学号</th><th>姓名</th><th>年龄</th><th>性别</th><th>薪资</th><th>就业城市</th><th>操作</th></tr></thead><tbody><!-- <tr><td>1001</td><td>欧阳霸天</td><td>19</td><td>男</td><td>15000</td><td>上海</td><td><a href="javascript:">删除</a></td></tr> --></tbody></table><script>// 获取元素const uname = document.querySelector('.uname');const age = document.querySelector('.age');const gender = document.querySelector('.gender');const salary = document.querySelector('.salary');const city = document.querySelector('.city');const items = document.querySelectorAll('[name]');// 存储对象数据const arr = [];// 表单提交事件const info = document.querySelector('.info');// submit事件info.addEventListener('submit', function (e) {// 先阻止默认行为e.preventDefault();// 表单验证for (let i = 0; i < items.length; i++) {// 验证输入内容,避免空内容// trim方法是字符串中的,并且.value也不一定是字符串类型,所以需要转化为字符串类型// 豆包解释// https://www.doubao.com/thread/wd8ab032dfb9df31bif (String(items[i].value).trim() === '') {alert('请完整填写');// 调用表单的reset方法,避免数据残留this.reset();return;}}// 创建对象并放进数组中const obj = {stuId: arr.length + 1,uname: uname.value,age: age.value,gender: gender.value,salary: salary.value,city: city.value,}arr.push(obj);// console.log(arr);// 表单的重置this.reset();render();})// const btn = document.createElement('button');// btn.type = 'reset';// btn.textContent = '重置';// info.appendChild(btn);const tbody = document.querySelector('tbody');function render() {// 渲染之前先清空tbody.innerHTML = '';for (let i = 0; i < arr.length; i++) {const tr = document.createElement('tr');tr.dataset.id = `${i}`;tr.innerHTML = `<td>${i + 1}</td><td>${arr[i].uname}</td><td>${arr[i].age}</td><td>${arr[i].gender}</td><td>${arr[i].salary}</td><td>${arr[i].city}</td><td><a href="javascript:">删除</a></td>`;tbody.appendChild(tr);}}tbody.addEventListener('click', function (e) {if (e.target.tagName === 'A') {arr.splice(e.target.parentNode.parentNode.dataset.id, 1);render();}});</script></body></html>