设计思路
-
使用响应式表格展示学生信息
-
添加和编辑功能通过模态框实现
-
简洁现代的UI设计
-
完整的搜索和筛选功能
详细代码如下:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>学生信息管理系统</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
body {
background: linear-gradient(135deg, #6a11cb 0%, #2575fc 100%);
color: #333;
min-height: 100vh;
padding: 20px;
display: flex;
flex-direction: column;
align-items: center;
}
.container {
width: 100%;
max-width: 1200px;
margin: 0 auto;
}
header {
text-align: center;
margin-bottom: 30px;
color: white;
}
h1 {
font-size: 2.5rem;
margin-bottom: 10px;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
}
.subtitle {
font-size: 1.2rem;
opacity: 0.9;
}
.controls {
display: flex;
justify-content: space-between;
margin-bottom: 30px;
flex-wrap: wrap;
gap: 15px;
background: white;
padding: 20px;
border-radius: 10px;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
}
.search-box {
display: flex;
flex: 1;
max-width: 500px;
min-width: 250px;
}
.search-box input {
flex: 1;
padding: 12px 20px;
border: 1px solid #ddd;
border-radius: 50px 0 0 50px;
font-size: 16px;
outline: none;
}
.search-box button {
padding: 12px 20px;
background: #ff6b6b;
color: white;
border: none;
border-radius: 0 50px 50px 0;
cursor: pointer;
transition: background 0.3s;
}
.search-box button:hover {
background: #ff5252;
}
.add-btn {
padding: 12px 25px;
background: #4CAF50;
color: white;
border: none;
border-radius: 50px;
cursor: pointer;
font-size: 16px;
font-weight: bold;
display: flex;
align-items: center;
gap: 8px;
transition: background 0.3s, transform 0.2s;
}
.add-btn:hover {
background: #45a049;
transform: translateY(-2px);
}
.table-container {
background: white;
border-radius: 10px;
overflow: hidden;
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.15);
overflow-x: auto;
}
table {
width: 100%;
border-collapse: collapse;
}
thead {
background: #3f51b5;
color: white;
}
th, td {
padding: 15px;
text-align: left;
border-bottom: 1px solid #ddd;
}
th {
font-weight: 600;
}
tbody tr:hover {
background-color: #f5f5f5;
}
.action-buttons {
display: flex;
gap: 10px;
}
.btn {
padding: 6px 12px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
display: flex;
align-items: center;
gap: 5px;
transition: all 0.3s;
}
.btn-edit {
background: #ff9800;
color: white;
}
.btn-edit:hover {
background: #f57c00;
}
.btn-delete {
background: #f44336;
color: white;
}
.btn-delete:hover {
background: #d32f2f;
}
/* Modal Styles */
.modal {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.7);
z-index: 1000;
justify-content: center;
align-items: center;
}
.modal-content {
background: white;
border-radius: 10px;
width: 90%;
max-width: 600px;
box-shadow: 0 15px 30px rgba(0, 0, 0, 0.3);
animation: modalFade 0.3s;
}
@keyframes modalFade {
from {
opacity: 0;
transform: translateY(-50px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.modal-header {
padding: 20px;
background: #3f51b5;
color: white;
border-radius: 10px 10px 0 0;
display: flex;
justify-content: space-between;
align-items: center;
}
.modal-title {
font-size: 1.5rem;
}
.close-btn {
background: none;
border: none;
color: white;
font-size: 1.5rem;
cursor: pointer;
transition: transform 0.2s;
}
.close-btn:hover {
transform: rotate(90deg);
}
.modal-body {
padding: 30px;
}
.form-group {
margin-bottom: 20px;
display: flex;
flex-wrap: wrap;
gap: 20px;
}
.form-group > div {
flex: 1;
min-width: 250px;
}
.form-group label {
display: block;
margin-bottom: 8px;
font-weight: 500;
color: #555;
}
.form-group input,
.form-group select {
width: 100%;
padding: 12px;
border: 1px solid #ddd;
border-radius: 5px;
font-size: 16px;
}
.modal-footer {
padding: 20px;
background: #f9f9f9;
border-radius: 0 0 10px 10px;
display: flex;
justify-content: flex-end;
gap: 10px;
}
.btn-cancel {
background: #9e9e9e;
color: white;
}
.btn-cancel:hover {
background: #757575;
}
.btn-submit {
background: #4CAF50;
color: white;
}
.btn-submit:hover {
background: #45a049;
}
.empty-state {
text-align: center;
padding: 50px;
}
.empty-state i {
font-size: 5rem;
color: #ccc;
margin-bottom: 20px;
}
.empty-state p {
font-size: 1.2rem;
color: #777;
margin-bottom: 30px;
}
/* Responsive Design */
@media (max-width: 768px) {
.controls {
flex-direction: column;
}
.search-box {
max-width: 100%;
}
th, td {
padding: 10px;
}
.action-buttons {
flex-direction: column;
}
}
.pagination {
display: flex;
justify-content: center;
margin-top: 20px;
gap: 10px;
}
.pagination button {
padding: 8px 15px;
background: #3f51b5;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
}
.pagination button:disabled {
background: #9e9e9e;
cursor: not-allowed;
}
</style>
</head>
<body>
<div class="container">
<header>
<h1>学生信息管理系统</h1>
<p class="subtitle">表格形式的增删改查功能</p>
</header>
<div class="controls">
<div class="search-box">
<input type="text" id="search-input" placeholder="搜索学生...">
<button id="search-btn"><i class="fas fa-search"></i> 搜索</button>
</div>
<button class="add-btn" id="add-btn">
<i class="fas fa-plus"></i> 添加新学生
</button>
</div>
<div class="table-container">
<table>
<thead>
<tr>
<th>ID</th>
<th>姓名</th>
<th>年龄</th>
<th>专业</th>
<th>成绩</th>
<th>入学日期</th>
<th>操作</th>
</tr>
</thead>
<tbody id="table-body">
<!-- 表格数据将通过JavaScript动态添加 -->
</tbody>
</table>
<div class="empty-state" id="empty-state">
<i class="fas fa-inbox"></i>
<p>暂无学生信息,点击"添加新学生"开始创建</p>
</div>
</div>
<div class="pagination" id="pagination">
<button id="prev-btn" disabled><i class="fas fa-chevron-left"></i> 上一页</button>
<span id="page-info">第 1 页</span>
<button id="next-btn">下一页 <i class="fas fa-chevron-right"></i></button>
</div>
</div>
<!-- 添加/编辑模态框 -->
<div class="modal" id="item-modal">
<div class="modal-content">
<div class="modal-header">
<h2 class="modal-title" id="modal-title">添加新学生</h2>
<button class="close-btn" id="close-modal">×</button>
</div>
<div class="modal-body">
<form id="item-form">
<input type="hidden" id="item-id">
<div class="form-group">
<div>
<label for="item-name">学生姓名</label>
<input type="text" id="item-name" required>
</div>
<div>
<label for="item-age">年龄</label>
<input type="number" id="item-age" min="16" max="30" required>
</div>
</div>
<div class="form-group">
<div>
<label for="item-major">专业</label>
<select id="item-major" required>
<option value="">请选择专业</option>
<option value="计算机科学">计算机科学</option>
<option value="电子工程">电子工程</option>
<option value="工商管理">工商管理</option>
<option value="机械工程">机械工程</option>
<option value="外语">外语</option>
</select>
</div>
<div>
<label for="item-grade">成绩</label>
<input type="number" id="item-grade" min="0" max="100" step="0.1" required>
</div>
</div>
<div class="form-group">
<div>
<label for="item-date">入学日期</label>
<input type="date" id="item-date" required>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button class="btn btn-cancel" id="cancel-btn">取消</button>
<button class="btn btn-submit" id="submit-btn">提交</button>
</div>
</div>
</div>
<script>
// 示例数据
let items = [
{ id: 1, name: "张三", age: 20, major: "计算机科学", grade: 92.5, date: "2023-09-01" },
{ id: 2, name: "李四", age: 21, major: "电子工程", grade: 88.0, date: "2023-09-01" },
{ id: 3, name: "王五", age: 19, major: "工商管理", grade: 76.5, date: "2023-09-01" },
{ id: 4, name: "赵六", age: 22, major: "机械工程", grade: 85.5, date: "2023-09-01" },
{ id: 5, name: "钱七", age: 20, major: "外语", grade: 91.0, date: "2023-09-01" },
{ id: 6, name: "孙八", age: 21, major: "计算机科学", grade: 79.5, date: "2023-09-01" },
{ id: 7, name: "周九", age: 19, major: "电子工程", grade: 87.0, date: "2023-09-01" },
{ id: 8, name: "吴十", age: 20, major: "工商管理", grade: 82.5, date: "2023-09-01" }
];
// DOM元素
const tableBody = document.getElementById('table-body');
const emptyState = document.getElementById('empty-state');
const itemModal = document.getElementById('item-modal');
const modalTitle = document.getElementById('modal-title');
const itemForm = document.getElementById('item-form');
const itemId = document.getElementById('item-id');
const itemName = document.getElementById('item-name');
const itemAge = document.getElementById('item-age');
const itemMajor = document.getElementById('item-major');
const itemGrade = document.getElementById('item-grade');
const itemDate = document.getElementById('item-date');
const addBtn = document.getElementById('add-btn');
const closeModal = document.getElementById('close-modal');
const cancelBtn = document.getElementById('cancel-btn');
const submitBtn = document.getElementById('submit-btn');
const searchInput = document.getElementById('search-input');
const searchBtn = document.getElementById('search-btn');
const prevBtn = document.getElementById('prev-btn');
const nextBtn = document.getElementById('next-btn');
const pageInfo = document.getElementById('page-info');
// 分页相关变量
let currentPage = 1;
const itemsPerPage = 5;
let filteredItems = [...items];
// 显示表格数据
function renderTable() {
tableBody.innerHTML = '';
if (filteredItems.length === 0) {
emptyState.style.display = 'block';
return;
}
emptyState.style.display = 'none';
// 计算当前页的数据
const startIndex = (currentPage - 1) * itemsPerPage;
const endIndex = Math.min(startIndex + itemsPerPage, filteredItems.length);
const currentItems = filteredItems.slice(startIndex, endIndex);
currentItems.forEach(item => {
const row = document.createElement('tr');
row.innerHTML = `
<td>${item.id}</td>
<td>${item.name}</td>
<td>${item.age}</td>
<td>${item.major}</td>
<td>${item.grade}</td>
<td>${item.date}</td>
<td>
<div class="action-buttons">
<button class="btn btn-edit" data-id="${item.id}">
<i class="fas fa-edit"></i> 编辑
</button>
<button class="btn btn-delete" data-id="${item.id}">
<i class="fas fa-trash"></i> 删除
</button>
</div>
</td>
`;
tableBody.appendChild(row);
});
// 更新分页按钮状态
updatePagination();
// 添加编辑和删除事件监听
document.querySelectorAll('.btn-edit').forEach(btn => {
btn.addEventListener('click', (e) => {
const id = parseInt(e.target.closest('.btn-edit').dataset.id);
editItem(id);
});
});
document.querySelectorAll('.btn-delete').forEach(btn => {
btn.addEventListener('click', (e) => {
const id = parseInt(e.target.closest('.btn-delete').dataset.id);
deleteItem(id);
});
});
}
// 更新分页状态
function updatePagination() {
const totalPages = Math.ceil(filteredItems.length / itemsPerPage);
pageInfo.textContent = `第 ${currentPage} 页 / 共 ${totalPages} 页`;
prevBtn.disabled = currentPage === 1;
nextBtn.disabled = currentPage === totalPages || totalPages === 0;
}
// 添加新项目
function addItem() {
modalTitle.textContent = '添加新学生';
itemForm.reset();
itemId.value = '';
itemModal.style.display = 'flex';
}
// 编辑项目
function editItem(id) {
const item = items.find(item => item.id === id);
if (item) {
modalTitle.textContent = '编辑学生信息';
itemId.value = item.id;
itemName.value = item.name;
itemAge.value = item.age;
itemMajor.value = item.major;
itemGrade.value = item.grade;
itemDate.value = item.date;
itemModal.style.display = 'flex';
}
}
// 删除项目
function deleteItem(id) {
if (confirm('确定要删除这个学生信息吗?')) {
items = items.filter(item => item.id !== id);
filteredItems = filteredItems.filter(item => item.id !== id);
// 如果当前页没有数据了,且不是第一页,则跳转到上一页
if (filteredItems.length <= (currentPage - 1) * itemsPerPage && currentPage > 1) {
currentPage--;
}
renderTable();
}
}
// 保存项目(添加或更新)
function saveItem() {
const id = itemId.value ? parseInt(itemId.value) : Date.now();
const name = itemName.value;
const age = parseInt(itemAge.value);
const major = itemMajor.value;
const grade = parseFloat(itemGrade.value);
const date = itemDate.value;
if (!name || !age || !major || !grade || !date) {
alert('请填写所有字段');
return;
}
if (itemId.value) {
// 更新现有项目
const index = items.findIndex(item => item.id === id);
if (index !== -1) {
items[index] = { id, name, age, major, grade, date };
}
} else {
// 添加新项目
items.push({ id, name, age, major, grade, date });
}
// 更新过滤后的列表
const query = searchInput.value.toLowerCase();
if (query) {
filteredItems = items.filter(item =>
item.name.toLowerCase().includes(query) ||
item.major.toLowerCase().includes(query)
);
} else {
filteredItems = [...items];
}
renderTable();
closeItemModal();
}
// 关闭模态框
function closeItemModal() {
itemModal.style.display = 'none';
}
// 搜索项目
function searchItems() {
const query = searchInput.value.toLowerCase();
if (!query) {
filteredItems = [...items];
} else {
filteredItems = items.filter(item =>
item.name.toLowerCase().includes(query) ||
item.major.toLowerCase().includes(query)
);
}
currentPage = 1;
renderTable();
}
// 事件监听
addBtn.addEventListener('click', addItem);
closeModal.addEventListener('click', closeItemModal);
cancelBtn.addEventListener('click', closeItemModal);
submitBtn.addEventListener('click', saveItem);
searchBtn.addEventListener('click', searchItems);
searchInput.addEventListener('keyup', (e) => {
if (e.key === 'Enter') {
searchItems();
}
});
prevBtn.addEventListener('click', () => {
if (currentPage > 1) {
currentPage--;
renderTable();
}
});
nextBtn.addEventListener('click', () => {
const totalPages = Math.ceil(filteredItems.length / itemsPerPage);
if (currentPage < totalPages) {
currentPage++;
renderTable();
}
});
// 点击模态框外部关闭
window.addEventListener('click', (e) => {
if (e.target === itemModal) {
closeItemModal();
}
});
// 初始化渲染
filteredItems = [...items];
renderTable();
</script>
</body>
</html>