引言
欢迎来到HTML5的世界!如果你是完全的编程新手,或者想要系统地学习网页开发,那么你来对地方了。HTML5是构建现代网页和Web应用的基石,它定义了网页的结构和内容。本指南将带你从零开始,逐步掌握HTML5的核心概念、语法和实战技巧,让你能够独立创建功能丰富的网页。
为什么学习HTML5?
- 现代Web标准:HTML5是当前Web开发的最新标准,支持丰富的多媒体、图形和交互功能。
- 跨平台兼容:HTML5网页可以在各种设备上运行,包括桌面、手机和平板。
- 职业发展:掌握HTML5是成为前端开发者、全栈开发者或Web设计师的必备技能。
- 社区支持:拥有庞大的开发者社区和丰富的学习资源。
第一部分:HTML5基础概念
1.1 什么是HTML5?
HTML(HyperText Markup Language)是一种标记语言,用于创建网页的结构。HTML5是HTML的第五次重大修订,引入了许多新特性,如语义化标签、多媒体支持、图形绘制、本地存储等。
1.2 HTML5文档结构
一个基本的HTML5文档结构如下:
<!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>
<!-- 页面内容将在这里编写 -->
</body>
</html>
代码解释:
<!DOCTYPE html>:声明文档类型为HTML5。<html>:根元素,lang属性指定语言为中文。<head>:包含文档的元数据,如字符集、视口设置和标题。<meta charset="UTF-8">:指定字符编码为UTF-8,支持中文。<meta name="viewport">:确保页面在移动设备上正确缩放。<title>:定义浏览器标签页的标题。<body>:包含所有可见内容,如文本、图像、链接等。
1.3 HTML5标签与属性
HTML5使用标签来定义元素。标签通常成对出现,如<p>和</p>。属性提供额外信息,如<a href="https://example.com">链接</a>。
常见标签:
- 标题:
<h1>到<h6> - 段落:
<p> - 链接:
<a> - 图像:
<img> - 列表:
<ul>(无序)、<ol>(有序)、<li> - 表格:
<table>,<tr>,<td>,<th>
HTML5新特性:
- 语义化标签:
<header>,<nav>,<section>,<article>,<footer>等,用于描述内容结构。 - 多媒体标签:
<audio>,<video>,<canvas>。 - 表单增强:
<input>类型如email,date,range等。
第二部分:HTML5核心技能
2.1 语义化标签
语义化标签让代码更易读,并有助于SEO和可访问性。
示例:创建一个简单的博客页面结构
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>我的博客</title>
</head>
<body>
<header>
<h1>我的博客</h1>
<nav>
<ul>
<li><a href="#home">首页</a></li>
<li><a href="#about">关于</a></li>
<li><a href="#contact">联系</a></li>
</ul>
</nav>
</header>
<main>
<article>
<h2>HTML5入门指南</h2>
<p>HTML5是构建现代网页的核心技术...</p>
<section>
<h3>为什么学习HTML5?</h3>
<p>HTML5提供了丰富的API和特性...</p>
</section>
</article>
</main>
<footer>
<p>© 2023 我的博客. 保留所有权利。</p>
</footer>
</body>
</html>
解释:
<header>:定义页面或文章的头部。<nav>:定义导航链接。<main>:定义主要内容区域。<article>:定义独立的内容块(如博客文章)。<section>:定义文档中的一个区域或主题。<footer>:定义页面或文章的页脚。
2.2 多媒体元素
HTML5原生支持音频和视频,无需插件。
示例:嵌入视频和音频
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>多媒体示例</title>
</head>
<body>
<h1>视频播放器</h1>
<video controls width="640" height="360" poster="poster.jpg">
<source src="movie.mp4" type="video/mp4">
<source src="movie.webm" type="video/webm">
您的浏览器不支持视频标签。
</video>
<h1>音频播放器</h1>
<audio controls>
<source src="audio.mp3" type="audio/mpeg">
<source src="audio.ogg" type="audio/ogg">
您的浏览器不支持音频标签。
</audio>
</body>
</html>
解释:
<video>:嵌入视频,controls属性显示播放控件。<source>:指定多个媒体源,浏览器会选择支持的格式。<audio>:嵌入音频,用法类似视频。poster:视频未加载时显示的封面图。
2.3 表单与输入
HTML5表单增强了用户体验,提供了新的输入类型和验证。
示例:用户注册表单
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>注册表单</title>
</head>
<body>
<h1>用户注册</h1>
<form action="/submit" method="post">
<label for="username">用户名:</label>
<input type="text" id="username" name="username" required minlength="3" maxlength="20">
<br><br>
<label for="email">邮箱:</label>
<input type="email" id="email" name="email" required>
<br><br>
<label for="password">密码:</label>
<input type="password" id="password" name="password" required minlength="8">
<br><br>
<label for="birthdate">出生日期:</label>
<input type="date" id="birthdate" name="birthdate">
<br><br>
<label for="age">年龄:</label>
<input type="range" id="age" name="age" min="18" max="100" value="25">
<span id="ageValue">25</span>
<br><br>
<label for="avatar">上传头像:</label>
<input type="file" id="avatar" name="avatar" accept="image/*">
<br><br>
<label for="bio">个人简介:</label>
<textarea id="bio" name="bio" rows="4" cols="50"></textarea>
<br><br>
<input type="submit" value="注册">
</form>
<script>
// 简单的JavaScript来更新范围滑块的值
const ageInput = document.getElementById('age');
const ageValue = document.getElementById('ageValue');
ageInput.addEventListener('input', function() {
ageValue.textContent = this.value;
});
</script>
</body>
</html>
解释:
required:字段必填。minlength/maxlength:文本长度限制。type="email":自动验证邮箱格式。type="date":日期选择器。type="range":滑块控件。type="file":文件上传。<textarea>:多行文本输入。<label>:提高可访问性,点击标签可聚焦输入框。
2.4 图形与绘图
HTML5引入了<canvas>元素,允许通过JavaScript动态绘制图形。
示例:使用Canvas绘制一个简单的图形
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-UTF-8">
<title>Canvas绘图</title>
<style>
canvas {
border: 1px solid #ccc;
display: block;
margin: 20px auto;
}
</style>
</head>
<body>
<h1>Canvas绘图示例</h1>
<canvas id="myCanvas" width="400" height="200"></canvas>
<script>
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
// 绘制矩形
ctx.fillStyle = 'blue';
ctx.fillRect(10, 10, 150, 80);
// 绘制圆形
ctx.beginPath();
ctx.arc(250, 50, 40, 0, 2 * Math.PI);
ctx.fillStyle = 'red';
ctx.fill();
// 绘制文本
ctx.fillStyle = 'black';
ctx.font = '20px Arial';
ctx.fillText('Hello Canvas!', 10, 150);
// 绘制线条
ctx.beginPath();
ctx.moveTo(10, 180);
ctx.lineTo(390, 180);
ctx.strokeStyle = 'green';
ctx.lineWidth = 2;
ctx.stroke();
</script>
</body>
</html>
解释:
<canvas>:定义绘图区域,通过JavaScript的getContext('2d')获取2D绘图上下文。fillRect(x, y, width, height):绘制填充矩形。arc(x, y, radius, startAngle, endAngle):绘制圆弧。fillText(text, x, y):绘制文本。moveTo(x, y)和lineTo(x, y):绘制路径线条。
第三部分:实战技巧与最佳实践
3.1 响应式设计基础
响应式设计确保网页在不同设备上都能良好显示。使用HTML5的<meta>标签和CSS媒体查询。
示例:响应式布局基础
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>响应式示例</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
}
.container {
width: 100%;
max-width: 1200px;
margin: 0 auto;
padding: 20px;
}
.header {
background-color: #333;
color: white;
padding: 20px;
text-align: center;
}
.main-content {
display: flex;
flex-wrap: wrap;
gap: 20px;
margin-top: 20px;
}
.sidebar {
flex: 1;
min-width: 200px;
background-color: #f4f4f4;
padding: 15px;
}
.content {
flex: 3;
min-width: 300px;
background-color: #fff;
padding: 15px;
}
.footer {
background-color: #333;
color: white;
padding: 20px;
text-align: center;
margin-top: 20px;
}
/* 媒体查询:当屏幕宽度小于768px时,调整布局 */
@media (max-width: 768px) {
.main-content {
flex-direction: column;
}
.sidebar, .content {
flex: none;
width: 100%;
}
}
</style>
</head>
<body>
<div class="container">
<header class="header">
<h1>响应式网站标题</h1>
</header>
<div class="main-content">
<aside class="sidebar">
<h3>侧边栏</h3>
<p>这里是侧边栏内容。</p>
</aside>
<main class="content">
<h2>主要内容</h2>
<p>这里是主要内容区域。当屏幕变小时,布局会自动调整。</p>
</main>
</div>
<footer class="footer">
<p>© 2023 响应式网站示例</p>
</footer>
</div>
</body>
</html>
解释:
<meta name="viewport">:确保移动设备正确缩放。- CSS Flexbox:创建灵活的布局。
- 媒体查询:根据屏幕尺寸应用不同样式。
3.2 表单验证与用户体验
HTML5内置表单验证,但结合JavaScript可以提供更友好的体验。
示例:增强的表单验证
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>增强表单验证</title>
<style>
.error {
color: red;
font-size: 0.9em;
display: none;
}
input:invalid {
border-color: red;
}
input:valid {
border-color: green;
}
</style>
</head>
<body>
<h1>用户反馈表单</h1>
<form id="feedbackForm">
<label for="name">姓名:</label>
<input type="text" id="name" name="name" required minlength="2">
<span class="error" id="nameError">姓名至少需要2个字符</span>
<br><br>
<label for="email">邮箱:</label>
<input type="email" id="email" name="email" required>
<span class="error" id="emailError">请输入有效的邮箱地址</span>
<br><br>
<label for="message">反馈内容:</label>
<textarea id="message" name="message" required minlength="10"></textarea>
<span class="error" id="messageError">反馈内容至少需要10个字符</span>
<br><br>
<input type="submit" value="提交反馈">
</form>
<script>
const form = document.getElementById('feedbackForm');
const nameInput = document.getElementById('name');
const emailInput = document.getElementById('email');
const messageInput = document.getElementById('message');
const nameError = document.getElementById('nameError');
const emailError = document.getElementById('emailError');
const messageError = document.getElementById('messageError');
// 实时验证
nameInput.addEventListener('input', function() {
if (nameInput.value.length < 2) {
nameError.style.display = 'block';
} else {
nameError.style.display = 'none';
}
});
emailInput.addEventListener('input', function() {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(emailInput.value)) {
emailError.style.display = 'block';
} else {
emailError.style.display = 'none';
}
});
messageInput.addEventListener('input', function() {
if (messageInput.value.length < 10) {
messageError.style.display = 'block';
} else {
messageError.style.display = 'none';
}
});
// 表单提交验证
form.addEventListener('submit', function(e) {
let isValid = true;
if (nameInput.value.length < 2) {
nameError.style.display = 'block';
isValid = false;
}
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(emailInput.value)) {
emailError.style.display = 'block';
isValid = false;
}
if (messageInput.value.length < 10) {
messageError.style.display = 'block';
isValid = false;
}
if (!isValid) {
e.preventDefault(); // 阻止表单提交
alert('请修正表单错误后再提交。');
}
});
</script>
</body>
</html>
解释:
required、minlength等HTML5属性提供基本验证。- CSS伪类
:invalid和:valid提供视觉反馈。 - JavaScript添加实时验证和自定义错误消息。
3.3 本地存储与离线应用
HTML5提供了Web Storage(localStorage和sessionStorage)和IndexedDB,用于在客户端存储数据。
示例:使用localStorage保存用户偏好
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>本地存储示例</title>
<style>
body {
font-family: Arial, sans-serif;
padding: 20px;
}
.theme-selector {
margin-bottom: 20px;
}
.content {
padding: 20px;
border: 1px solid #ccc;
transition: background-color 0.3s, color 0.3s;
}
.light-theme {
background-color: #fff;
color: #000;
}
.dark-theme {
background-color: #333;
color: #fff;
}
</style>
</head>
<body>
<h1>本地存储示例</h1>
<div class="theme-selector">
<label>选择主题:</label>
<select id="themeSelect">
<option value="light">浅色主题</option>
<option value="dark">深色主题</option>
</select>
<button id="saveTheme">保存主题</button>
<button id="clearStorage">清除存储</button>
</div>
<div class="content light-theme" id="content">
<h2>示例内容</h2>
<p>这个页面的主题偏好会保存在本地存储中,即使刷新页面也会保持。</p>
<p>点击“保存主题”按钮将当前选择保存到localStorage。</p>
</div>
<script>
const themeSelect = document.getElementById('themeSelect');
const saveButton = document.getElementById('saveTheme');
const clearButton = document.getElementById('clearStorage');
const content = document.getElementById('content');
// 页面加载时,从localStorage读取主题
window.addEventListener('DOMContentLoaded', function() {
const savedTheme = localStorage.getItem('theme');
if (savedTheme) {
themeSelect.value = savedTheme;
applyTheme(savedTheme);
}
});
// 保存主题
saveButton.addEventListener('click', function() {
const selectedTheme = themeSelect.value;
localStorage.setItem('theme', selectedTheme);
applyTheme(selectedTheme);
alert('主题已保存!');
});
// 清除存储
clearButton.addEventListener('click', function() {
localStorage.removeItem('theme');
themeSelect.value = 'light';
applyTheme('light');
alert('存储已清除!');
});
// 应用主题
function applyTheme(theme) {
content.className = 'content ' + theme + '-theme';
}
</script>
</body>
</html>
解释:
localStorage.setItem(key, value):存储数据,数据在浏览器关闭后仍保留。localStorage.getItem(key):读取数据。localStorage.removeItem(key):删除特定数据。localStorage.clear():清除所有数据(本例未使用)。
3.4 无障碍访问(Accessibility)
确保网页对所有人(包括残障人士)都可访问。
示例:添加ARIA属性
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>无障碍访问示例</title>
<style>
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
.nav-menu {
list-style: none;
padding: 0;
display: flex;
gap: 10px;
}
.nav-menu li a {
padding: 10px;
background-color: #f0f0f0;
text-decoration: none;
color: #333;
}
.nav-menu li a:focus {
outline: 2px solid blue;
background-color: #e0e0e0;
}
.button {
padding: 10px 20px;
background-color: #007bff;
color: white;
border: none;
cursor: pointer;
}
.button:focus {
outline: 2px solid orange;
}
</style>
</head>
<body>
<h1>无障碍访问示例</h1>
<!-- 使用ARIA属性的导航 -->
<nav aria-label="主导航">
<ul class="nav-menu">
<li><a href="#home" aria-current="page">首页</a></li>
<li><a href="#about">关于</a></li>
<li><a href="#services">服务</a></li>
<li><a href="#contact">联系</a></li>
</ul>
</nav>
<!-- 使用ARIA属性的按钮 -->
<button class="button" aria-label="关闭弹窗" onclick="alert('按钮被点击')">
<span aria-hidden="true">✕</span>
<span class="sr-only">关闭</span>
</button>
<!-- 使用ARIA属性的表单 -->
<form aria-labelledby="formTitle">
<h2 id="formTitle">联系表单</h2>
<div>
<label for="name">姓名:</label>
<input type="text" id="name" name="name" aria-required="true" aria-describedby="nameDesc">
<span id="nameDesc" class="sr-only">请输入您的全名</span>
</div>
<div>
<label for="email">邮箱:</label>
<input type="email" id="email" name="email" aria-required="true" aria-describedby="emailDesc">
<span id="emailDesc" class="sr-only">我们将通过此邮箱与您联系</span>
</div>
<button type="submit" class="button">提交</button>
</form>
<!-- 使用ARIA属性的动态内容 -->
<div id="status" role="status" aria-live="polite" aria-atomic="true">
<!-- 动态消息将在这里显示 -->
</div>
<script>
// 模拟动态更新状态消息
const statusDiv = document.getElementById('status');
setTimeout(() => {
statusDiv.textContent = '表单提交成功!感谢您的反馈。';
}, 2000);
</script>
</body>
</html>
解释:
aria-label:为元素提供可访问的名称。aria-current="page":指示当前页面。aria-hidden="true":隐藏装饰性元素。sr-only类:视觉隐藏但屏幕阅读器可读。aria-required:指示必填字段。aria-describedby:关联描述文本。role="status"和aria-live="polite":动态内容更新时通知屏幕阅读器。
第四部分:项目实战
4.1 项目1:个人简历页面
目标:创建一个响应式的个人简历页面,展示个人信息、教育背景、工作经验和技能。
步骤:
- 规划结构:使用语义化标签组织内容。
- 编写HTML:创建基本结构。
- 添加CSS:实现响应式布局和样式。
- 测试:在不同设备上测试。
示例代码:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>张三的简历</title>
<style>
/* 基础样式 */
body {
font-family: 'Arial', sans-serif;
line-height: 1.6;
color: #333;
margin: 0;
padding: 0;
background-color: #f9f9f9;
}
.container {
max-width: 800px;
margin: 20px auto;
padding: 20px;
background: white;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
header {
text-align: center;
border-bottom: 2px solid #007bff;
padding-bottom: 20px;
margin-bottom: 20px;
}
h1 {
color: #007bff;
margin: 0;
}
.contact-info {
margin-top: 10px;
font-size: 0.9em;
color: #666;
}
section {
margin-bottom: 25px;
}
h2 {
color: #007bff;
border-bottom: 1px solid #eee;
padding-bottom: 5px;
}
.skill-bar {
background-color: #eee;
border-radius: 5px;
margin: 5px 0;
overflow: hidden;
}
.skill-level {
height: 20px;
background-color: #007bff;
text-align: center;
color: white;
font-size: 0.8em;
line-height: 20px;
}
.experience-item, .education-item {
margin-bottom: 15px;
}
.experience-item h3, .education-item h3 {
margin: 0;
color: #333;
}
.experience-item p, .education-item p {
margin: 5px 0;
color: #666;
font-size: 0.9em;
}
/* 响应式设计 */
@media (max-width: 600px) {
.container {
margin: 10px;
padding: 15px;
}
header {
padding-bottom: 15px;
}
h1 {
font-size: 1.5em;
}
}
</style>
</head>
<body>
<div class="container">
<header>
<h1>张三</h1>
<div class="contact-info">
<p>电话:138-0000-0000 | 邮箱:zhangsan@example.com | 地址:北京市朝阳区</p>
</div>
</header>
<main>
<section id="summary">
<h2>个人简介</h2>
<p>我是一名充满热情的前端开发者,拥有3年的Web开发经验。擅长HTML5、CSS3和JavaScript,对响应式设计和用户体验有深入理解。目前正在学习Vue.js和React框架。</p>
</section>
<section id="skills">
<h2>专业技能</h2>
<div class="skill-item">
<p>HTML5/CSS3</p>
<div class="skill-bar">
<div class="skill-level" style="width: 90%;">90%</div>
</div>
</div>
<div class="skill-item">
<p>JavaScript</p>
<div class="skill-bar">
<div class="skill-level" style="width: 85%;">85%</div>
</div>
</div>
<div class="skill-item">
<p>响应式设计</p>
<div class="skill-bar">
<div class="skill-level" style="width: 80%;">80%</div>
</div>
</div>
<div class="skill-item">
<p>Git版本控制</p>
<div class="skill-bar">
<div class="skill-level" style="width: 75%;">75%</div>
</div>
</div>
</section>
<section id="experience">
<h2>工作经验</h2>
<div class="experience-item">
<h3>前端开发工程师 - ABC科技有限公司</h3>
<p>2021年6月 - 至今</p>
<ul>
<li>负责公司官网的前端开发和维护</li>
<li>使用HTML5、CSS3和JavaScript开发响应式页面</li>
<li>与设计师和后端工程师协作,确保项目按时交付</li>
</ul>
</div>
<div class="experience-item">
<h3>Web开发实习生 - XYZ互联网公司</h3>
<p>2020年7月 - 2021年5月</p>
<ul>
<li>参与内部管理系统的前端开发</li>
<li>学习并应用Vue.js框架</li>
<li>编写技术文档和用户手册</li>
</ul>
</div>
</section>
<section id="education">
<h2>教育背景</h2>
<div class="education-item">
<h3>计算机科学与技术 - 本科</h3>
<p>北京大学 | 2016年9月 - 2020年6月</p>
<p>主修课程:数据结构、算法、Web开发、数据库系统</p>
</div>
</section>
</main>
<footer>
<p style="text-align: center; color: #666; font-size: 0.8em; margin-top: 30px;">
© 2023 张三. 保留所有权利。
</p>
</footer>
</div>
</body>
</html>
4.2 项目2:交互式待办事项列表
目标:创建一个简单的待办事项列表,使用HTML5、CSS和JavaScript实现添加、删除和标记完成的功能。
步骤:
- HTML结构:创建表单和列表容器。
- CSS样式:美化界面。
- JavaScript逻辑:处理用户交互和数据存储。
示例代码:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>待办事项列表</title>
<style>
body {
font-family: 'Arial', sans-serif;
background-color: #f5f5f5;
margin: 0;
padding: 20px;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
.todo-container {
background: white;
border-radius: 10px;
box-shadow: 0 4px 15px rgba(0,0,0,0.1);
width: 100%;
max-width: 500px;
padding: 25px;
}
h1 {
text-align: center;
color: #333;
margin-bottom: 20px;
}
.input-section {
display: flex;
gap: 10px;
margin-bottom: 20px;
}
#todoInput {
flex: 1;
padding: 12px;
border: 2px solid #ddd;
border-radius: 5px;
font-size: 16px;
transition: border-color 0.3s;
}
#todoInput:focus {
outline: none;
border-color: #007bff;
}
#addBtn {
padding: 12px 20px;
background-color: #007bff;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 16px;
transition: background-color 0.3s;
}
#addBtn:hover {
background-color: #0056b3;
}
#todoList {
list-style: none;
padding: 0;
margin: 0;
}
.todo-item {
display: flex;
align-items: center;
padding: 12px;
background-color: #f9f9f9;
border-radius: 5px;
margin-bottom: 8px;
transition: background-color 0.3s;
}
.todo-item:hover {
background-color: #e9e9e9;
}
.todo-item.completed {
background-color: #e8f5e9;
text-decoration: line-through;
color: #666;
}
.todo-item input[type="checkbox"] {
margin-right: 12px;
width: 18px;
height: 18px;
cursor: pointer;
}
.todo-text {
flex: 1;
font-size: 16px;
cursor: pointer;
}
.delete-btn {
background-color: #ff4d4d;
color: white;
border: none;
padding: 6px 12px;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
transition: background-color 0.3s;
}
.delete-btn:hover {
background-color: #e60000;
}
.empty-message {
text-align: center;
color: #999;
padding: 20px;
font-style: italic;
}
.stats {
display: flex;
justify-content: space-between;
margin-top: 20px;
padding-top: 15px;
border-top: 1px solid #eee;
color: #666;
font-size: 14px;
}
</style>
</head>
<body>
<div class="todo-container">
<h1>待办事项列表</h1>
<div class="input-section">
<input type="text" id="todoInput" placeholder="添加新任务..." maxlength="100">
<button id="addBtn">添加</button>
</div>
<ul id="todoList"></ul>
<div class="stats">
<span id="totalTasks">总任务: 0</span>
<span id="completedTasks">已完成: 0</span>
<span id="pendingTasks">待完成: 0</span>
</div>
</div>
<script>
// 获取DOM元素
const todoInput = document.getElementById('todoInput');
const addBtn = document.getElementById('addBtn');
const todoList = document.getElementById('todoList');
const totalTasks = document.getElementById('totalTasks');
const completedTasks = document.getElementById('completedTasks');
const pendingTasks = document.getElementById('pendingTasks');
// 从localStorage加载任务
let todos = JSON.parse(localStorage.getItem('todos')) || [];
// 初始化
function init() {
renderTodos();
updateStats();
}
// 渲染任务列表
function renderTodos() {
todoList.innerHTML = '';
if (todos.length === 0) {
todoList.innerHTML = '<div class="empty-message">暂无任务,添加一个吧!</div>';
return;
}
todos.forEach((todo, index) => {
const li = document.createElement('li');
li.className = `todo-item ${todo.completed ? 'completed' : ''}`;
li.innerHTML = `
<input type="checkbox" ${todo.completed ? 'checked' : ''}
onchange="toggleComplete(${index})">
<span class="todo-text" onclick="toggleComplete(${index})">${todo.text}</span>
<button class="delete-btn" onclick="deleteTodo(${index})">删除</button>
`;
todoList.appendChild(li);
});
}
// 更新统计信息
function updateStats() {
const total = todos.length;
const completed = todos.filter(todo => todo.completed).length;
const pending = total - completed;
totalTasks.textContent = `总任务: ${total}`;
completedTasks.textContent = `已完成: ${completed}`;
pendingTasks.textContent = `待完成: ${pending}`;
}
// 保存到localStorage
function saveToStorage() {
localStorage.setItem('todos', JSON.stringify(todos));
}
// 添加新任务
function addTodo() {
const text = todoInput.value.trim();
if (text === '') {
alert('请输入任务内容!');
return;
}
const newTodo = {
text: text,
completed: false,
createdAt: new Date().toISOString()
};
todos.push(newTodo);
saveToStorage();
renderTodos();
updateStats();
todoInput.value = '';
todoInput.focus();
}
// 切换完成状态
function toggleComplete(index) {
todos[index].completed = !todos[index].completed;
saveToStorage();
renderTodos();
updateStats();
}
// 删除任务
function deleteTodo(index) {
if (confirm('确定要删除这个任务吗?')) {
todos.splice(index, 1);
saveToStorage();
renderTodos();
updateStats();
}
}
// 事件监听
addBtn.addEventListener('click', addTodo);
todoInput.addEventListener('keypress', function(e) {
if (e.key === 'Enter') {
addTodo();
}
});
// 初始化应用
init();
</script>
</body>
</html>
第五部分:学习资源与进阶路径
5.1 推荐学习资源
官方文档:
- MDN Web Docs (https://developer.mozilla.org/zh-CN/docs/Web/HTML)
- W3Schools (https://www.w3schools.com/html/)
- HTML5规范 (https://html.spec.whatwg.org/)
在线课程:
- freeCodeCamp (https://www.freecodecamp.org/)
- Coursera上的Web开发专项课程
- Udemy上的HTML5完整课程
书籍推荐:
- 《HTML5与CSS3权威指南》
- 《深入理解HTML5:语义、标准与样式》
- 《JavaScript高级程序设计》
工具与编辑器:
- Visual Studio Code (推荐)
- Sublime Text
- Chrome开发者工具
5.2 进阶学习路径
CSS深入学习:
- Flexbox和Grid布局
- CSS动画和过渡
- 预处理器(Sass/Less)
JavaScript基础:
- ES6+新特性
- DOM操作和事件处理
- 异步编程(Promise, async/await)
前端框架:
- React.js
- Vue.js
- Angular
工具链:
- 包管理器(npm/yarn)
- 构建工具(Webpack/Vite)
- 版本控制(Git)
项目实践:
- 个人项目(博客、电商网站)
- 开源项目贡献
- 参加编程挑战(如LeetCode前端题目)
5.3 常见问题与解决方案
问题1:HTML5标签在旧浏览器中不显示
- 解决方案:使用Polyfill或提供降级方案。例如,对于
<canvas>,可以提供备用内容。
问题2:表单验证不工作
- 解决方案:确保浏览器支持HTML5验证,或使用JavaScript进行自定义验证。
问题3:响应式设计在移动设备上显示异常
- 解决方案:检查viewport meta标签,使用媒体查询测试不同设备。
问题4:本地存储数据丢失
- 解决方案:检查浏览器隐私设置,确保未启用无痕模式或清除数据。
结语
通过本指南,你已经从零开始学习了HTML5的核心概念、语法和实战技巧。记住,编程是一个持续学习的过程,实践是最好的老师。建议你从简单的项目开始,逐步挑战更复杂的应用。
下一步行动:
- 创建一个个人项目(如个人网站或博客)
- 学习CSS和JavaScript以增强你的网页
- 加入开发者社区(如GitHub、Stack Overflow)
- 持续练习和构建项目
祝你在网页开发的旅程中取得成功!
