教程概述
本教程将分为以下几个部分:

- 准备工作:了解我们需要的工具。
- 第一步:创建静态页面结构:使用 HTML5 搭建网页的骨架。
- 第二步:美化页面样式:使用 CSS 让网页变得好看。
- 第三步:注入动态灵魂(核心):使用 JavaScript 让页面“活”起来。
- 第四步:优化与扩展:添加更多功能和改进用户体验。
- 总结与进阶方向:回顾所学,并指出未来可以探索的方向。
第一步:准备工作
你不需要任何复杂的软件!只需要一个文本编辑器和一个网页浏览器。
- 文本编辑器:
- 推荐:Visual Studio Code (VS Code) (免费、强大、有智能提示)
- 备选:Sublime Text, Atom, 或者系统自带的记事本(不推荐,功能太弱)。
- 网页浏览器:
- 推荐:Google Chrome (它的开发者工具非常出色,便于调试)。
- 备选:Firefox, Edge, Safari。
项目结构:
在你的电脑上创建一个新文件夹,命名为 todo-app,在这个文件夹里,我们将创建三个文件:
index.html(存放网页结构)style.css(存放网页样式)script.js(存放网页行为/逻辑)
第二步:创建静态页面结构 (HTML5)
HTML (HyperText Markup Language) 是网页的骨架,它定义了内容的结构和含义。

打开 index.html 文件,输入以下代码:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">我的待办事项列表</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
<h1>我的待办事项</h1>
<div class="input-container">
<input type="text" id="todo-input" placeholder="添加一个新的待办事项...">
<button id="add-btn">添加</button>
</div>
<ul id="todo-list">
<!-- 待办事项将在这里动态生成 -->
<li class="todo-item">
<span>学习 HTML5</span>
<button class="delete-btn">删除</button>
</li>
<li class="todo-item">
<span>学习 JavaScript</span>
<button class="delete-btn">删除</button>
</li>
</ul>
</div>
<script src="script.js"></script>
</body>
</html>
代码解析:
<!DOCTYPE html>:声明这是一个 HTML5 文档。<html lang="zh-CN">:整个网页的根元素,lang属性指定语言为中文。<head>:包含网页的元数据,如标题、字符编码、引入的样式表等。<body>:包含网页的所有可见内容。<div class="container">:一个容器,用于包裹所有内容,方便布局。<h1>。<input>:一个文本输入框,id="todo-input"是它的唯一标识,方便 JS 操作。<button id="add-btn">:一个按钮,id="add-btn"也是它的唯一标识。<ul id="todo-list">:一个无序列表,id="todo-list"是我们动态添加待办事项的目标区域。<li class="todo-item">:列表项,也就是每一个待办事项。<span>:用于包裹待办事项的文本。<button class="delete-btn">:删除按钮,class="delete-btn"用于样式和事件绑定。<script src="script.js"></script>:在</body>结束标签前引入我们的 JavaScript 文件,这是一种最佳实践,确保页面内容加载完毕后再执行脚本。
在浏览器中打开 index.html,你应该能看到一个简单的、静态的待办事项列表界面。
第三步:美化页面样式
CSS (Cascading Style Sheets) 负责网页的视觉呈现,如颜色、字体、布局等。
打开 style.css 文件,输入以下代码:
/* 基础样式重置 */
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: 'Arial', sans-serif;
background-color: #f4f4f4;
color: #333;
line-height: 1.6;
}
.container {
max-width: 600px;
margin: 30px auto;
padding: 20px;
background: #fff;
border-radius: 5px;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
}
h1 {
text-align: center;
color: #333;
margin-bottom: 20px;
}
.input-container {
display: flex;
margin-bottom: 20px;
}
#todo-input {
flex: 1;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px 0 0 4px;
font-size: 16px;
}
#add-btn {
padding: 10px 15px;
border: none;
background: #5cb85c;
color: white;
cursor: pointer;
font-size: 16px;
border-radius: 0 4px 4px 0;
transition: background 0.3s;
}
#add-btn:hover {
background: #4cae4c;
}
#todo-list {
list-style: none;
}
.todo-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px;
background: #f9f9f9;
border-bottom: 1px solid #ddd;
transition: background 0.3s;
}
.todo-item:last-child {
border-bottom: none;
}
.todo-item span {
flex-grow: 1;
}
.delete-btn {
padding: 5px 10px;
border: none;
background: #d9534f;
color: white;
cursor: pointer;
border-radius: 3px;
transition: background 0.3s;
}
.delete-btn:hover {
background: #c9302c;
}
保存后,刷新浏览器,你的页面应该会变得美观许多。
第四步:注入动态灵魂 (JavaScript)
这是最关键的一步,JavaScript 将让我们的网页响应用户的操作。
打开 script.js 文件,我们将分步实现功能。
功能 1:添加新的待办事项
// 1. 获取DOM元素
const todoInput = document.getElementById('todo-input');
const addBtn = document.getElementById('add-btn');
const todoList = document.getElementById('todo-list');
// 2. 定义“添加”任务的函数
function addTodo() {
// 获取输入框的值,并去除首尾空格
const todoText = todoInput.value.trim();
// 如果输入为空,则不执行任何操作
if (todoText === '') {
alert('请输入待办事项!');
return;
}
// 创建新的列表项 <li>
const li = document.createElement('li');
li.className = 'todo-item';
// 创建文本 <span>
const span = document.createElement('span');
span.textContent = todoText;
// 创建删除按钮 <button>
const deleteBtn = document.createElement('button');
deleteBtn.className = 'delete-btn';
deleteBtn.textContent = '删除';
// 将 <span> 和 <button> 添加到 <li> 中
li.appendChild(span);
li.appendChild(deleteBtn);
// 将新的 <li> 添加到 <ul> 列表的末尾
todoList.appendChild(li);
// 添加任务后,清空输入框
todoInput.value = '';
}
// 3. 为“添加”按钮绑定点击事件
addBtn.addEventListener('click', addTodo);
// 4. (可选) 允许用户按回车键添加任务
todoInput.addEventListener('keypress', function(event) {
if (event.key === 'Enter') {
addTodo();
}
});
代码解析:
document.getElementById():通过id获取 HTML 元素。document.createElement():动态创建一个新的 HTML 元素。element.textContent:设置或获取元素的文本内容。element.appendChild():将一个子元素添加到父元素的末尾。element.addEventListener('click', functionName):为元素绑定一个点击事件,当元素被点击时,执行指定的函数。event.key === 'Enter':检查按下的键是否是回车键。
测试:在输入框中输入文字,点击“添加”按钮或按回车,新的待办事项应该会出现在列表中。
功能 2:删除待办事项
我们不能为每个删除按钮单独绑定事件,因为任务列表是动态生成的,更好的方法是事件委托:我们给父元素(todoList)绑定一个事件,然后通过判断事件的目标元素(event.target)来决定执行什么操作。
修改 script.js 文件,在现有代码的末尾添加以下代码:
// 在 script.js 的末尾添加
// 5. 定义“删除”任务的函数(使用事件委托)
function deleteTodo(event) {
// 检查点击的是否是删除按钮
if (event.target.classList.contains('delete-btn')) {
// event.target 是被点击的按钮
// event.target.parentElement 是按钮的父元素,也就是 <li>
const li = event.target.parentElement;
// 添加一个淡出动画(可选,更友好)
li.style.transition = 'opacity 0.5s';
li.style.opacity = '0';
// 等待动画结束后再移除元素
setTimeout(() => {
li.remove();
}, 500);
}
}
// 6. 为待办事项列表 <ul> 绑定点击事件
todoList.addEventListener('click', deleteTodo);
代码解析:
event.target:触发事件的原始元素。element.classList.contains('class-name'):检查元素是否包含指定的 CSS 类。element.parentElement:获取元素的父元素。element.remove():从 DOM 中移除一个元素。setTimeout(function, milliseconds):在指定的毫秒数后执行一次函数,这里我们用它来等待 CSS 动画播放完毕。
测试:点击任何一个待办事项旁边的“删除”按钮,该任务应该会淡出并从列表中消失。
第五步:优化与扩展
我们的应用已经可以工作了,但还可以变得更好。
优化 1:使用 localStorage 持久化数据
刷新页面后,所有待办事项都会丢失,我们可以使用浏览器的 localStorage 来保存数据,这样刷新后数据依然存在。
修改 script.js:
// ... (前面的代码保持不变)
// --- 新增的辅助函数 ---
// 从 localStorage 加载待办事项
function loadTodos() {
const todos = JSON.parse(localStorage.getItem('todos')) || [];
todos.forEach(todoText => {
// 为了避免重复添加事件监听器,我们直接创建HTML字符串然后插入
// 或者调用一个内部函数来创建,这里为了简单,我们直接操作DOM
const li = document.createElement('li');
li.className = 'todo-item';
li.innerHTML = `
<span>${todoText}</span>
<button class="delete-btn">删除</button>
`;
todoList.appendChild(li);
});
}
// 保存待办事项到 localStorage
function saveTodos() {
const todos = [];
const todoSpans = todoList.querySelectorAll('span');
todoSpans.forEach(span => {
todos.push(span.textContent);
});
localStorage.setItem('todos', JSON.stringify(todos));
}
// --- 修改现有的函数 ---
// 修改 addTodo 函数
function addTodo() {
const todoText = todoInput.value.trim();
if (todoText === '') {
alert('请输入待办事项!');
return;
}
const li = document.createElement('li');
li.className = 'todo-item';
li.innerHTML = `
<span>${todoText}</span>
<button class="delete-btn">删除</button>
`;
todoList.appendChild(li);
// 新增:保存到 localStorage
saveTodos();
todoInput.value = '';
}
// 修改 deleteTodo 函数
function deleteTodo(event) {
if (event.target.classList.contains('delete-btn')) {
const li = event.target.parentElement;
li.style.transition = 'opacity 0.5s';
li.style.opacity = '0';
setTimeout(() => {
li.remove();
// 新增:保存到 localStorage
saveTodos();
}, 500);
}
}
// --- 初始化 ---
// 页面加载时,先加载本地存储的待办事项
loadTodos();
// ... (后面的代码保持不变)
代码解析:
localStorage.setItem('key', 'value'):将数据存储到本地,数据以字符串形式保存。localStorage.getItem('key'):从本地获取数据。JSON.stringify():将 JavaScript 对象/数组转换为 JSON 字符串。JSON.parse():将 JSON 字符串解析为 JavaScript 对象/数组。
无论你怎么刷新页面,你的待办事项都会被保留。
第六步:总结与进阶方向
恭喜你!你已经成功创建了一个功能完整的动态网页。
我们学到了什么?
- HTML5:如何构建网页的语义化结构。
- CSS:如何美化网页,实现响应式布局和过渡效果。
- JavaScript:如何操作 DOM 元素,实现用户交互,以及如何使用
localStorage实现数据持久化。 - 核心概念:事件监听、事件委托、动态创建元素。
可以探索的进阶方向:
- 更复杂的状态管理:使用
class来管理每个待办事项的状态(如已完成、未完成),并添加复选框。 - 前端框架:学习使用 Vue.js, React 或 Angular,它们能让你更高效、更结构化地构建大型动态应用。
- API 交互:学习使用
fetchAPI 或axios库,让你的应用与后端服务器进行数据交换,实现多用户同步等功能。 - 路由:学习使用
React Router或Vue Router构建多页面应用。 - CSS 框架:学习使用 Tailwind CSS 或 Bootstrap,快速构建美观的界面。
希望这份教程能帮助你开启动态网页开发的大门!动手实践是学习编程最好的方式。
