一、学习目标
掌握 JavaScript DOM 操作、事件绑定、本地存储(localStorage),实现一个可添加、删除、修改、勾选的 TodoList,适合前端入门或想巩固 DOM 操作的程序员。
二、核心知识点
- DOM 操作:创建元素、删除元素、修改元素内容与样式
- 事件绑定:click、input 事件,事件委托(优化性能)
- localStorage:本地存储数据,实现页面刷新后数据不丢失
- 数组方法:forEach、filter、map 的实际应用
三、实战代码(可直接运行,复制到 HTML 文件即可)
html
预览
<html lang="zh-CN">
<head>
<meta charset="UTF-8<meta name="viewport" content="width=device-width, initial-scale=1.0">
简易TodoList
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Arial', sans-serif;
}
.container {
width: 500px;
margin: 50px auto;
padding: 20px;
border: 1px solid #eee;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0,0,0,0.1);
}
h1 {
text-align: center;
margin-bottom: 20px;
color: #333;
}
.add-todo {
display: flex;
gap: 10px;
margin-bottom: 20px;
}
#todo-input {
flex: 1;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 16px;
}
#add-btn {
padding: 0 20px;
background: #4CAF50;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
}
#add-btn:hover {
background: #45a049;
}
.todo-list {
list-style: none;
}
.todo-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px;
border-bottom: 1px solid #eee;
}
.todo-item:hover {
background: #f9f9f9;
}
.todo-content {
display: flex;
align-items: center;
gap: 10px;
}
.todo-checkbox:checked + span {
text-decoration: line-through;
color: #999;
}
.todo-operate {
display: flex;
gap: 10px;
}
.edit-btn {
color: #2196F3;
border: none;
background: transparent;
cursor: pointer;
}
.delete-btn {
color: #f44336;
border: none;
background: transparent;
cursor: pointer;
}
</head>
<body>
<div class="container">
<h1>Todo</h1>
<div class="add-todo">
<input type="text" id="todo-input" placeholder="请输入待办事项...<button id="add-btn">添加</div<ul class="todo-list" id="</ul>
</div>
<script>
// 1. 获取DOM元素
const todoInput = document.getElementById('todo-input');
const addBtn = document.getElementById('add-btn');
const todoList = document.getElementById('todo-list');
// 2. 从本地存储获取todo数据,没有则初始化空数组
let todos = JSON.parse(localStorage.getItem('todos')) || [];
// 3. 渲染todo列表
function renderTodo() {
// 清空列表,避免重复渲染
todoList.innerHTML = '';
// 遍历todos数组,创建每个todo项
todos.forEach((todo, index) => {
const li = document.createElement('li');
li.className = 'todo-item';
li.innerHTML = `<div class="todo-content">
<input type="checkbox" class="todo-checkbox" ${todo.done ? 'checked' : ''}>
</span</div><div class="todo-operate">
<button class="edit-btn</button>
<button class="delete</button></div>
`;
// 将li添加到列表中
todoList.appendChild(li);
// 4. 绑定事件(勾选、编辑、删除)
// 勾选事件
const checkbox = li.querySelector('.todo-checkbox');
checkbox.addEventListener('click', () => {
todos[index].done = !todos[index].done;
// 更新本地存储并重新渲染
updateLocalStorage();
renderTodo();
});
// 编辑事件
const editBtn = li.querySelector('.edit-btn');
editBtn.addEventListener('click', () => {
const newContent = prompt('请输入修改后的待办事项:', todo.content);
if (newContent && newContent.trim() !== '') {
todos[index].content = newContent.trim();
updateLocalStorage();
renderTodo();
}
});
// 删除事件
const deleteBtn = li.querySelector('.delete-btn');
deleteBtn.addEventListener('click', () => {
if (confirm('确定要删除这个待办事项吗?')) {
todos.splice(index, 1);
updateLocalStorage();
renderTodo();
}
});
});
}
// 5. 添加todo任务
function addTodo() {
const content = todoInput.value.trim();
if (content === '') {
alert('请输入待办事项!');
return;
}
// 新增todo对象
const newTodo = {
content: content,
done: false // 初始状态:未勾选
};
todos.push(newTodo);
// 更新本地存储并重新渲染
updateLocalStorage();
renderTodo();
// 清空输入框
todoInput.value = '';
}
// 6. 更新本地存储
function updateLocalStorage() {
localStorage.setItem('todos', JSON.stringify(todos));
}
// 7. 绑定添加按钮点击事件
addBtn.addEventListener('click', addTodo);
// 绑定回车键事件(按下回车也能添加)
todoInput.addEventListener('keydown', (e) => {
if (e.key === 'Enter') {
addTodo();
}
});
// 8. 页面加载时渲染todo列表
window.addEventListener('load', render</script</body>
</html>
四、代码说明与功能演示
- 功能说明:可添加待办事项、勾选完成、编辑内容、删除事项,页面刷新后数据不会丢失(通过 localStorage 存储)。
- 运行方法:将代码复制到记事本,保存为.html 文件(如 todo.html),用浏览器打开即可使用。
- 核心亮点:使用事件委托的思想(虽然本案例直接绑定,但可优化为事件委托,减少事件绑定数量),localStorage 实现数据持久化,数组方法处理 todo 数据。
五、拓展练习
尝试添加 "清空已完成""按完成状态筛选" 功能,巩固 DOM 操作和数组方法的使用;或优化样式,实现响应式布局,适配手机端。