引言:为什么选择HTML5前端开发?
在当今数字化时代,前端开发已成为互联网行业的核心技能之一。HTML5作为现代Web开发的基石,不仅提供了丰富的语义化标签,还集成了强大的多媒体、图形和本地存储功能。从零基础开始学习HTML5前端开发,不仅能让你掌握构建现代网站和应用的能力,还能为后续学习CSS、JavaScript及各种前端框架打下坚实基础。
本攻略将带你从最基础的HTML标签开始,逐步深入到CSS样式、JavaScript交互,最终通过实战项目巩固所学知识。无论你是完全的编程新手,还是希望系统提升前端技能的开发者,都能在这里找到适合自己的学习路径。
第一部分:HTML5基础入门
1.1 HTML5简介与开发环境搭建
HTML5是HTML的第五次重大修订,它引入了大量新特性,如语义化标签、表单增强、Canvas绘图、Web Storage等。首先,我们需要搭建一个简单的开发环境。
开发工具推荐:
- 文本编辑器:VS Code(推荐)、Sublime Text、Atom
- 浏览器:Chrome(开发者工具强大)、Firefox
- 本地服务器:Live Server(VS Code插件)或Python内置服务器
创建第一个HTML文件:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>我的第一个HTML5页面</title>
</head>
<body>
<h1>欢迎来到HTML5世界!</h1>
<p>这是一个简单的段落。</p>
</body>
</html>
代码解析:
<!DOCTYPE html>:声明文档类型为HTML5<html lang="zh-CN">:根元素,指定语言为中文<head>:包含文档的元数据<meta charset="UTF-8">:指定字符编码<meta name="viewport">:移动端视口设置<body>:页面可见内容
1.2 HTML5语义化标签
HTML5引入了大量语义化标签,使代码结构更清晰,对SEO和可访问性更友好。
常用语义化标签:
<header>
<nav>
<ul>
<li><a href="#home">首页</a></li>
<li><a href="#about">关于</a></li>
</ul>
</nav>
</header>
<main>
<article>
<h2>文章标题</h2>
<p>文章内容...</p>
<section>
<h3>章节1</h3>
<p>章节内容...</p>
</section>
</article>
<aside>
<h3>侧边栏</h3>
<p>相关链接...</p>
</aside>
</main>
<footer>
<p>© 2023 我的网站</p>
</footer>
语义化标签的优势:
- SEO优化:搜索引擎更容易理解页面结构
- 可访问性:屏幕阅读器能更好地解析页面
- 代码可读性:开发者能快速理解页面布局
1.3 HTML5表单增强
HTML5为表单元素带来了许多新特性和输入类型。
新输入类型示例:
<form>
<!-- 邮箱验证 -->
<label for="email">邮箱:</label>
<input type="email" id="email" required>
<!-- 日期选择器 -->
<label for="birthdate">出生日期:</label>
<input type="date" id="birthdate">
<!-- 颜色选择器 -->
<label for="color">选择颜色:</label>
<input type="color" id="color">
<!-- 滑块 -->
<label for="volume">音量:</label>
<input type="range" id="volume" min="0" max="100" value="50">
<!-- 搜索框 -->
<label for="search">搜索:</label>
<input type="search" id="search" placeholder="输入关键词...">
<!-- 数字输入 -->
<label for="quantity">数量:</label>
<input type="number" id="quantity" min="1" max="10" step="1">
<!-- 提交按钮 -->
<button type="submit">提交</button>
</form>
HTML5表单验证:
<form>
<label for="username">用户名(必填,至少3个字符):</label>
<input type="text" id="username" required minlength="3">
<label for="password">密码(必填,至少8个字符):</label>
<input type="password" id="password" required minlength="8">
<label for="phone">电话(格式验证):</label>
<input type="tel" id="phone" pattern="[0-9]{11}" placeholder="11位手机号">
<button type="submit">注册</button>
</form>
第二部分:CSS3样式设计
2.1 CSS基础语法与选择器
CSS用于控制HTML元素的样式。我们可以通过多种方式引入CSS:
内联样式:
<p style="color: red; font-size: 16px;">这是一个段落</p>
内部样式表:
<head>
<style>
p {
color: blue;
font-size: 18px;
}
</style>
</head>
外部样式表(推荐):
<head>
<link rel="stylesheet" href="styles.css">
</head>
CSS选择器示例:
/* 元素选择器 */
p {
color: #333;
line-height: 1.6;
}
/* 类选择器 */
.highlight {
background-color: yellow;
padding: 5px;
}
/* ID选择器 */
#header {
background-color: #2c3e50;
color: white;
padding: 20px;
}
/* 后代选择器 */
nav ul li {
list-style: none;
display: inline-block;
}
/* 伪类选择器 */
a:hover {
color: #e74c3c;
text-decoration: underline;
}
/* 属性选择器 */
input[type="text"] {
border: 1px solid #ccc;
padding: 8px;
}
2.2 盒模型与布局
CSS盒模型是理解布局的基础,包括内容(content)、内边距(padding)、边框(border)和外边距(margin)。
盒模型示例:
.box {
width: 200px;
height: 100px;
padding: 20px;
border: 2px solid #333;
margin: 30px;
background-color: #f0f0f0;
/* 标准盒模型:width只包含内容宽度 */
box-sizing: content-box; /* 默认值 */
/* 总宽度 = 200 + 20*2 + 2*2 + 30*2 = 284px */
}
.box-border-box {
/* 怪异盒模型:width包含内容、padding和border */
box-sizing: border-box;
width: 200px; /* 总宽度就是200px */
}
Flexbox布局(弹性盒子):
.container {
display: flex;
justify-content: space-between; /* 主轴对齐 */
align-items: center; /* 交叉轴对齐 */
flex-wrap: wrap; /* 允许换行 */
gap: 20px; /* 元素间距 */
}
.item {
flex: 1; /* 等分空间 */
min-width: 150px;
background-color: #3498db;
padding: 20px;
color: white;
text-align: center;
}
Grid布局(网格布局):
.grid-container {
display: grid;
grid-template-columns: repeat(3, 1fr); /* 3列,等宽 */
grid-template-rows: auto;
gap: 15px;
padding: 20px;
}
.grid-item {
background-color: #2ecc71;
padding: 30px;
text-align: center;
color: white;
}
/* 响应式网格 */
@media (max-width: 768px) {
.grid-container {
grid-template-columns: 1fr; /* 移动端单列 */
}
}
2.3 CSS3动画与过渡
CSS3提供了强大的动画和过渡效果。
过渡效果示例:
.button {
background-color: #3498db;
color: white;
padding: 12px 24px;
border: none;
border-radius: 4px;
cursor: pointer;
transition: all 0.3s ease; /* 所有属性过渡,0.3秒,缓动函数 */
}
.button:hover {
background-color: #2980b9;
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(0,0,0,0.2);
}
关键帧动画示例:
/* 定义动画 */
@keyframes slideIn {
0% {
transform: translateX(-100%);
opacity: 0;
}
100% {
transform: translateX(0);
opacity: 1;
}
}
@keyframes pulse {
0%, 100% {
transform: scale(1);
}
50% {
transform: scale(1.1);
}
}
/* 应用动画 */
.animated-box {
width: 200px;
height: 100px;
background-color: #e74c3c;
margin: 20px;
animation: slideIn 1s ease-out, pulse 2s infinite 1s;
/* 第一个动画:slideIn,持续1秒,缓动函数ease-out */
/* 第二个动画:pulse,持续2秒,无限循环,延迟1秒开始 */
}
第三部分:JavaScript交互编程
3.1 JavaScript基础语法
JavaScript是前端开发的核心语言,用于实现页面交互。
变量与数据类型:
// 变量声明
let name = "张三"; // 块级作用域
const age = 25; // 常量,不可重新赋值
var oldVar = "旧变量"; // 函数作用域(不推荐使用)
// 数据类型
const str = "字符串";
const num = 42;
const bool = true;
const obj = { key: "value" };
const arr = [1, 2, 3];
const nullValue = null;
const undefinedValue = undefined;
// 模板字符串
const message = `你好,${name}!今年${age}岁。`;
console.log(message); // 你好,张三!今年25岁。
函数与箭头函数:
// 传统函数
function greet(name) {
return `你好,${name}!`;
}
// 箭头函数
const greetArrow = (name) => `你好,${name}!`;
// 高阶函数
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(num => num * 2); // [2, 4, 6, 8, 10]
const evens = numbers.filter(num => num % 2 === 0); // [2, 4]
const sum = numbers.reduce((acc, curr) => acc + curr, 0); // 15
3.2 DOM操作与事件处理
DOM(文档对象模型)是JavaScript操作HTML页面的接口。
DOM查询与修改:
// 获取元素
const header = document.getElementById('header');
const paragraphs = document.getElementsByTagName('p');
const items = document.querySelectorAll('.item');
// 修改内容
header.textContent = "新的标题";
header.innerHTML = "<strong>加粗的标题</strong>";
// 修改样式
header.style.color = "red";
header.style.backgroundColor = "#f0f0f0";
header.style.padding = "20px";
// 添加/删除类
header.classList.add('active');
header.classList.remove('inactive');
header.classList.toggle('highlight');
// 创建和添加元素
const newDiv = document.createElement('div');
newDiv.textContent = "新创建的div";
newDiv.className = "new-element";
document.body.appendChild(newDiv);
事件处理:
// 事件监听器
const button = document.getElementById('myButton');
// 点击事件
button.addEventListener('click', function(event) {
console.log('按钮被点击了!');
console.log('事件对象:', event);
});
// 鼠标事件
button.addEventListener('mouseenter', function() {
this.style.backgroundColor = '#2ecc71';
});
button.addEventListener('mouseleave', function() {
this.style.backgroundColor = '#3498db';
});
// 表单事件
const input = document.getElementById('username');
input.addEventListener('input', function(event) {
console.log('当前输入值:', event.target.value);
});
// 键盘事件
document.addEventListener('keydown', function(event) {
if (event.key === 'Enter') {
console.log('回车键被按下');
}
});
// 事件委托(高效处理动态元素)
document.getElementById('list').addEventListener('click', function(event) {
if (event.target.tagName === 'LI') {
console.log('点击了列表项:', event.target.textContent);
}
});
3.3 异步编程与AJAX
现代Web应用离不开异步操作和数据请求。
Promise与async/await:
// Promise示例
function fetchData(url) {
return new Promise((resolve, reject) => {
fetch(url)
.then(response => {
if (!response.ok) {
throw new Error('网络响应不正常');
}
return response.json();
})
.then(data => resolve(data))
.catch(error => reject(error));
});
}
// 使用async/await
async function getUserData() {
try {
const response = await fetch('https://api.example.com/users');
const users = await response.json();
console.log('用户数据:', users);
return users;
} catch (error) {
console.error('获取数据失败:', error);
return [];
}
}
// 并行请求
async function fetchMultipleData() {
const [users, posts] = await Promise.all([
fetch('https://api.example.com/users').then(r => r.json()),
fetch('https://api.example.com/posts').then(r => r.json())
]);
console.log('用户:', users);
console.log('文章:', posts);
}
AJAX请求示例:
// 使用fetch API
function loadUsers() {
fetch('https://jsonplaceholder.typicode.com/users')
.then(response => response.json())
.then(users => {
const userList = document.getElementById('user-list');
userList.innerHTML = ''; // 清空列表
users.forEach(user => {
const li = document.createElement('li');
li.textContent = `${user.name} (${user.email})`;
userList.appendChild(li);
});
})
.catch(error => {
console.error('加载用户失败:', error);
document.getElementById('user-list').innerHTML = '<li>加载失败</li>';
});
}
// 带参数的POST请求
async function createUser(userData) {
try {
const response = await fetch('https://api.example.com/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(userData)
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const newUser = await response.json();
console.log('创建用户成功:', newUser);
return newUser;
} catch (error) {
console.error('创建用户失败:', error);
throw error;
}
}
第四部分:响应式设计与移动端适配
4.1 媒体查询与响应式布局
响应式设计确保网站在不同设备上都能良好显示。
媒体查询示例:
/* 基础样式(移动优先) */
.container {
width: 100%;
padding: 10px;
box-sizing: border-box;
}
/* 平板设备(768px及以上) */
@media (min-width: 768px) {
.container {
width: 750px;
margin: 0 auto;
padding: 20px;
}
.sidebar {
width: 30%;
float: left;
}
.main-content {
width: 70%;
float: right;
}
}
/* 桌面设备(1024px及以上) */
@media (min-width: 1024px) {
.container {
width: 960px;
padding: 30px;
}
.sidebar {
width: 25%;
}
.main-content {
width: 75%;
}
}
/* 大屏幕设备(1200px及以上) */
@media (min-width: 1200px) {
.container {
width: 1140px;
}
}
响应式图片:
<!-- 使用picture元素 -->
<picture>
<source media="(min-width: 1024px)" srcset="large.jpg">
<source media="(min-width: 768px)" srcset="medium.jpg">
<img src="small.jpg" alt="响应式图片" style="width: 100%;">
</picture>
<!-- 使用srcset属性 -->
<img src="small.jpg"
srcset="medium.jpg 1024w, large.jpg 2048w"
sizes="(max-width: 1024px) 100vw, 1024px"
alt="响应式图片">
4.2 移动端交互优化
触摸事件处理:
// 触摸事件
const touchArea = document.getElementById('touch-area');
touchArea.addEventListener('touchstart', function(event) {
event.preventDefault(); // 防止默认行为
console.log('触摸开始', event.touches[0].clientX, event.touches[0].clientY);
});
touchArea.addEventListener('touchmove', function(event) {
event.preventDefault();
console.log('触摸移动');
});
touchArea.addEventListener('touchend', function(event) {
console.log('触摸结束');
});
// 防止双击缩放
document.addEventListener('touchstart', function(event) {
if (event.touches.length > 1) {
event.preventDefault();
}
});
// 防止页面滚动
document.body.addEventListener('touchmove', function(event) {
if (!event.target.closest('.scrollable')) {
event.preventDefault();
}
}, { passive: false });
移动端性能优化:
// 使用requestAnimationFrame优化动画
function animate(element) {
let start = null;
const duration = 1000;
function step(timestamp) {
if (!start) start = timestamp;
const progress = timestamp - start;
const percentage = Math.min(progress / duration, 1);
// 更新元素位置
element.style.transform = `translateX(${percentage * 300}px)`;
if (percentage < 1) {
requestAnimationFrame(step);
}
}
requestAnimationFrame(step);
}
// 使用Intersection Observer懒加载
const lazyImages = document.querySelectorAll('img[data-src]');
const imageObserver = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
img.removeAttribute('data-src');
observer.unobserve(img);
}
});
});
lazyImages.forEach(img => imageObserver.observe(img));
第五部分:实战项目开发
5.1 项目一:个人博客网站
项目目标: 创建一个响应式的个人博客网站,包含首页、文章列表、文章详情页。
HTML结构:
<!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="style.css">
</head>
<body>
<header class="header">
<div class="container">
<h1 class="logo">我的博客</h1>
<nav class="nav">
<ul>
<li><a href="#home">首页</a></li>
<li><a href="#articles">文章</a></li>
<li><a href="#about">关于</a></li>
</ul>
</nav>
</div>
</header>
<main class="main container">
<section class="hero">
<h2>欢迎来到我的博客</h2>
<p>分享技术与生活</p>
</section>
<section class="articles">
<h3>最新文章</h3>
<div class="article-list">
<!-- 文章列表将通过JavaScript动态生成 -->
</div>
</section>
</main>
<footer class="footer">
<div class="container">
<p>© 2023 我的博客</p>
</div>
</footer>
<script src="script.js"></script>
</body>
</html>
CSS样式(style.css):
/* 重置样式 */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
line-height: 1.6;
color: #333;
background-color: #f9f9f9;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
}
/* 头部样式 */
.header {
background-color: #2c3e50;
color: white;
padding: 15px 0;
position: sticky;
top: 0;
z-index: 100;
}
.header .container {
display: flex;
justify-content: space-between;
align-items: center;
}
.logo {
font-size: 1.5rem;
font-weight: bold;
}
.nav ul {
display: flex;
list-style: none;
gap: 20px;
}
.nav a {
color: white;
text-decoration: none;
transition: color 0.3s;
}
.nav a:hover {
color: #3498db;
}
/* 主要内容 */
.main {
padding: 40px 0;
}
.hero {
text-align: center;
padding: 60px 20px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border-radius: 8px;
margin-bottom: 40px;
}
.hero h2 {
font-size: 2.5rem;
margin-bottom: 15px;
}
/* 文章列表 */
.articles h3 {
margin-bottom: 20px;
font-size: 1.8rem;
border-bottom: 2px solid #3498db;
padding-bottom: 10px;
}
.article-list {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 25px;
}
.article-card {
background: white;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
transition: transform 0.3s, box-shadow 0.3s;
}
.article-card:hover {
transform: translateY(-5px);
box-shadow: 0 5px 20px rgba(0,0,0,0.15);
}
.article-card img {
width: 100%;
height: 180px;
object-fit: cover;
}
.article-card-content {
padding: 20px;
}
.article-card h4 {
margin-bottom: 10px;
font-size: 1.2rem;
}
.article-card p {
color: #666;
font-size: 0.9rem;
margin-bottom: 15px;
}
.article-card .meta {
display: flex;
justify-content: space-between;
font-size: 0.8rem;
color: #999;
}
/* 页脚 */
.footer {
background-color: #2c3e50;
color: white;
text-align: center;
padding: 20px 0;
margin-top: 40px;
}
/* 响应式设计 */
@media (max-width: 768px) {
.header .container {
flex-direction: column;
gap: 15px;
}
.nav ul {
justify-content: center;
flex-wrap: wrap;
}
.hero h2 {
font-size: 1.8rem;
}
.article-list {
grid-template-columns: 1fr;
}
}
JavaScript功能(script.js):
// 模拟文章数据
const articles = [
{
id: 1,
title: "HTML5新特性详解",
excerpt: "探索HTML5带来的语义化标签、表单增强和多媒体支持...",
date: "2023-10-15",
author: "张三",
image: "https://via.placeholder.com/400x200?text=HTML5"
},
{
id: 2,
title: "CSS3动画实战技巧",
excerpt: "学习如何使用CSS3创建流畅的动画效果...",
date: "2023-10-10",
author: "李四",
image: "https://via.placeholder.com/400x200?text=CSS3"
},
{
id: 3,
title: "JavaScript异步编程",
excerpt: "深入理解Promise、async/await和异步编程模式...",
date: "2023-10-05",
author: "王五",
image: "https://via.placeholder.com/400x200?text=JavaScript"
}
];
// 渲染文章列表
function renderArticles() {
const articleList = document.querySelector('.article-list');
articles.forEach(article => {
const articleCard = document.createElement('article');
articleCard.className = 'article-card';
articleCard.innerHTML = `
<img src="${article.image}" alt="${article.title}">
<div class="article-card-content">
<h4>${article.title}</h4>
<p>${article.excerpt}</p>
<div class="meta">
<span>${article.date}</span>
<span>${article.author}</span>
</div>
</div>
`;
// 添加点击事件
articleCard.addEventListener('click', () => {
showArticleDetail(article);
});
articleList.appendChild(articleCard);
});
}
// 显示文章详情
function showArticleDetail(article) {
// 创建模态框
const modal = document.createElement('div');
modal.className = 'modal';
modal.innerHTML = `
<div class="modal-content">
<span class="close">×</span>
<h2>${article.title}</h2>
<p class="meta">${article.date} | ${article.author}</p>
<img src="${article.image}" alt="${article.title}" style="width:100%; margin: 20px 0;">
<p>${article.excerpt}</p>
<p>这里是文章的完整内容...</p>
</div>
`;
document.body.appendChild(modal);
// 关闭模态框
modal.querySelector('.close').addEventListener('click', () => {
document.body.removeChild(modal);
});
modal.addEventListener('click', (e) => {
if (e.target === modal) {
document.body.removeChild(modal);
}
});
}
// 页面加载完成后执行
document.addEventListener('DOMContentLoaded', () => {
renderArticles();
// 平滑滚动
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function(e) {
e.preventDefault();
const target = document.querySelector(this.getAttribute('href'));
if (target) {
target.scrollIntoView({
behavior: 'smooth'
});
}
});
});
});
5.2 项目二:任务管理器(Todo List)
项目目标: 创建一个功能完整的任务管理器,支持添加、删除、标记完成和筛选任务。
HTML结构:
<!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="todo.css">
</head>
<body>
<div class="todo-app">
<header class="app-header">
<h1>任务管理器</h1>
<div class="stats">
<span id="total">总任务:0</span>
<span id="completed">已完成:0</span>
<span id="pending">待完成:0</span>
</div>
</header>
<div class="todo-form">
<input type="text" id="taskInput" placeholder="输入新任务..." autocomplete="off">
<button id="addBtn">添加任务</button>
</div>
<div class="filter-buttons">
<button class="filter-btn active" data-filter="all">全部</button>
<button class="filter-btn" data-filter="active">待完成</button>
<button class="filter-btn" data-filter="completed">已完成</button>
</div>
<ul id="taskList" class="task-list">
<!-- 任务列表将通过JavaScript动态生成 -->
</ul>
</div>
<script src="todo.js"></script>
</body>
</html>
CSS样式(todo.css):
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
padding: 20px;
}
.todo-app {
background: white;
border-radius: 12px;
box-shadow: 0 10px 30px rgba(0,0,0,0.2);
width: 100%;
max-width: 500px;
overflow: hidden;
}
.app-header {
background: #2c3e50;
color: white;
padding: 20px;
text-align: center;
}
.app-header h1 {
font-size: 1.8rem;
margin-bottom: 10px;
}
.stats {
display: flex;
justify-content: space-around;
font-size: 0.9rem;
opacity: 0.9;
}
.todo-form {
display: flex;
padding: 20px;
gap: 10px;
border-bottom: 1px solid #eee;
}
#taskInput {
flex: 1;
padding: 12px 15px;
border: 2px solid #ddd;
border-radius: 6px;
font-size: 1rem;
transition: border-color 0.3s;
}
#taskInput:focus {
outline: none;
border-color: #3498db;
}
#addBtn {
background: #3498db;
color: white;
border: none;
padding: 12px 20px;
border-radius: 6px;
cursor: pointer;
font-weight: bold;
transition: background 0.3s;
}
#addBtn:hover {
background: #2980b9;
}
.filter-buttons {
display: flex;
padding: 10px 20px;
gap: 10px;
background: #f8f9fa;
}
.filter-btn {
flex: 1;
padding: 8px;
border: 1px solid #ddd;
background: white;
border-radius: 4px;
cursor: pointer;
transition: all 0.3s;
}
.filter-btn.active {
background: #3498db;
color: white;
border-color: #3498db;
}
.task-list {
list-style: none;
max-height: 400px;
overflow-y: auto;
}
.task-item {
display: flex;
align-items: center;
padding: 15px 20px;
border-bottom: 1px solid #eee;
transition: background 0.2s;
}
.task-item:hover {
background: #f8f9fa;
}
.task-item.completed {
opacity: 0.6;
}
.task-checkbox {
margin-right: 15px;
width: 20px;
height: 20px;
cursor: pointer;
}
.task-text {
flex: 1;
font-size: 1rem;
word-break: break-word;
}
.task-item.completed .task-text {
text-decoration: line-through;
color: #999;
}
.task-delete {
background: #e74c3c;
color: white;
border: none;
padding: 6px 12px;
border-radius: 4px;
cursor: pointer;
opacity: 0;
transition: opacity 0.3s;
}
.task-item:hover .task-delete {
opacity: 1;
}
.task-delete:hover {
background: #c0392b;
}
/* 空状态 */
.empty-state {
text-align: center;
padding: 40px 20px;
color: #999;
}
.empty-state p {
margin-top: 10px;
}
/* 动画效果 */
@keyframes slideIn {
from {
opacity: 0;
transform: translateY(-10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.task-item {
animation: slideIn 0.3s ease-out;
}
/* 响应式设计 */
@media (max-width: 480px) {
.todo-app {
border-radius: 0;
height: 100vh;
max-width: none;
}
.filter-buttons {
flex-wrap: wrap;
}
.filter-btn {
flex: 0 0 calc(50% - 5px);
}
}
JavaScript功能(todo.js):
class TodoManager {
constructor() {
this.tasks = JSON.parse(localStorage.getItem('tasks')) || [];
this.currentFilter = 'all';
this.init();
}
init() {
this.bindEvents();
this.render();
this.updateStats();
}
bindEvents() {
// 添加任务
const addBtn = document.getElementById('addBtn');
const taskInput = document.getElementById('taskInput');
addBtn.addEventListener('click', () => this.addTask());
taskInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter') this.addTask();
});
// 筛选按钮
document.querySelectorAll('.filter-btn').forEach(btn => {
btn.addEventListener('click', (e) => {
document.querySelectorAll('.filter-btn').forEach(b => b.classList.remove('active'));
e.target.classList.add('active');
this.currentFilter = e.target.dataset.filter;
this.render();
});
});
}
addTask() {
const input = document.getElementById('taskInput');
const text = input.value.trim();
if (!text) {
alert('请输入任务内容!');
return;
}
const task = {
id: Date.now(),
text: text,
completed: false,
createdAt: new Date().toISOString()
};
this.tasks.push(task);
this.saveToStorage();
this.render();
this.updateStats();
input.value = '';
input.focus();
}
deleteTask(id) {
this.tasks = this.tasks.filter(task => task.id !== id);
this.saveToStorage();
this.render();
this.updateStats();
}
toggleTask(id) {
const task = this.tasks.find(task => task.id === id);
if (task) {
task.completed = !task.completed;
this.saveToStorage();
this.render();
this.updateStats();
}
}
getFilteredTasks() {
switch (this.currentFilter) {
case 'active':
return this.tasks.filter(task => !task.completed);
case 'completed':
return this.tasks.filter(task => task.completed);
default:
return this.tasks;
}
}
render() {
const taskList = document.getElementById('taskList');
const filteredTasks = this.getFilteredTasks();
if (filteredTasks.length === 0) {
taskList.innerHTML = `
<li class="empty-state">
<p>暂无任务</p>
<p>添加一个新任务开始吧!</p>
</li>
`;
return;
}
taskList.innerHTML = filteredTasks.map(task => `
<li class="task-item ${task.completed ? 'completed' : ''}" data-id="${task.id}">
<input type="checkbox" class="task-checkbox"
${task.completed ? 'checked' : ''}
onchange="todoManager.toggleTask(${task.id})">
<span class="task-text">${this.escapeHtml(task.text)}</span>
<button class="task-delete" onclick="todoManager.deleteTask(${task.id})">删除</button>
</li>
`).join('');
}
updateStats() {
const total = this.tasks.length;
const completed = this.tasks.filter(task => task.completed).length;
const pending = total - completed;
document.getElementById('total').textContent = `总任务:${total}`;
document.getElementById('completed').textContent = `已完成:${completed}`;
document.getElementById('pending').textContent = `待完成:${pending}`;
}
saveToStorage() {
localStorage.setItem('tasks', JSON.stringify(this.tasks));
}
escapeHtml(text) {
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
}
// 初始化应用
const todoManager = new TodoManager();
第六部分:进阶学习与资源推荐
6.1 前端框架入门
Vue.js基础示例:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue.js示例</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<style>
.app {
max-width: 600px;
margin: 50px auto;
padding: 20px;
font-family: Arial, sans-serif;
}
.todo-input {
width: 100%;
padding: 10px;
margin-bottom: 10px;
border: 1px solid #ddd;
border-radius: 4px;
}
.todo-item {
padding: 10px;
border-bottom: 1px solid #eee;
display: flex;
justify-content: space-between;
align-items: center;
}
.completed {
text-decoration: line-through;
color: #999;
}
.btn {
padding: 5px 10px;
background: #e74c3c;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
</style>
</head>
<body>
<div id="app" class="app">
<h2>Vue.js Todo List</h2>
<input
type="text"
class="todo-input"
v-model="newTodo"
@keyup.enter="addTodo"
placeholder="添加新任务..."
>
<div v-for="todo in todos" :key="todo.id" class="todo-item">
<span :class="{ completed: todo.completed }" @click="toggleTodo(todo)">
{{ todo.text }}
</span>
<button class="btn" @click="removeTodo(todo)">删除</button>
</div>
</div>
<script>
new Vue({
el: '#app',
data: {
newTodo: '',
todos: [
{ id: 1, text: '学习Vue.js', completed: false },
{ id: 2, text: '完成项目', completed: true }
]
},
methods: {
addTodo() {
if (this.newTodo.trim()) {
this.todos.push({
id: Date.now(),
text: this.newTodo,
completed: false
});
this.newTodo = '';
}
},
removeTodo(todo) {
this.todos = this.todos.filter(t => t.id !== todo.id);
},
toggleTodo(todo) {
todo.completed = !todo.completed;
}
}
});
</script>
</body>
</html>
6.2 学习资源推荐
在线学习平台:
- MDN Web Docs - 最权威的Web技术文档
- freeCodeCamp - 免费的交互式编程课程
- Codecademy - 交互式编程学习平台
- W3Schools - 简明的Web技术教程
视频教程:
- YouTube频道:Traversy Media、The Net Ninja、Academind
- B站中文教程:黑马程序员、尚硅谷、慕课网
书籍推荐:
- 《JavaScript高级程序设计》(第4版)
- 《CSS世界》
- 《深入浅出Vue.js》
- 《你不知道的JavaScript》系列
实战项目资源:
- GitHub:搜索”HTML5 project”、”frontend project”
- CodePen:查看和学习前端创意作品
- Frontend Mentor:提供设计稿的实战项目
6.3 开发工具与调试技巧
浏览器开发者工具:
- Elements:检查和修改DOM元素
- Console:执行JavaScript代码和查看日志
- Network:监控网络请求
- Performance:分析页面性能
- Lighthouse:评估页面质量
VS Code插件推荐:
- Live Server - 实时预览
- Prettier - 代码格式化
- ESLint - 代码检查
- Auto Rename Tag - 自动重命名标签
- CSS Peek - CSS跳转
性能优化技巧:
- 图片优化:使用WebP格式,懒加载
- 代码压缩:使用Webpack、Vite等工具
- 缓存策略:合理使用浏览器缓存
- 减少HTTP请求:合并文件,使用CDN
结语
通过本攻略的学习,你已经从HTML5的基础知识开始,逐步掌握了CSS样式设计、JavaScript交互编程、响应式设计等核心技能,并通过两个实战项目巩固了所学知识。前端开发是一个持续学习的领域,新技术和新工具层出不穷。
下一步建议:
- 深入学习JavaScript:掌握ES6+特性,理解原型链、闭包、异步编程
- 学习前端框架:选择一个主流框架(React、Vue、Angular)深入学习
- 构建工具:学习Webpack、Vite等现代构建工具
- 版本控制:熟练使用Git和GitHub
- 持续实践:参与开源项目,构建个人作品集
记住,编程是一门实践的艺术。多写代码,多做项目,多思考问题,你一定能成为一名优秀的前端开发者!
祝你学习顺利,编程愉快!
