前言
前两篇我们打好了基础,这一篇我们就要"起飞"了。我们会学习更多高级、更现代、更实用的知识点。
按照之前的"房子装修"比喻:
• 第一篇是认识工具(结构、装修、智能系统)
• 第二篇是学习使用工具的方法(表格、表单、盒模型、布局、循环)
• 这一篇是学习高级技巧 (多媒体、网格布局、动画、现代语法、事件处理、 异步编程)
准备好了吗?让我们开始这趟精彩的进阶之旅吧!
第一部分:HTML5新特性
HTML5是HTML的最新版本,它不仅仅是升级,更是一次革命。
1.1 什么是HTML5?
HTML5是HTML的第五个主要版本,于2014年正式成为W3C推荐标准。
核心改进 :
• 新增了语义化标签
• 新增了多媒体标签(音频、视频)
• 新增了表单验证功能
• 新增了本地存储功能
• 改进了Canvas绘图API
• 更好的浏览器兼容性
1.2 新增的语义化标签
在第二篇中,我们已经学习了一些语义化标签(header、nav、main、footer等)。HTML5还新增了一些。
新增语义化标签
|--------------|---------|---------------------------------------------------|
| 标签 | 作用 | 示例 |
| <article> | 独立的文章内容 | 博客文章、新闻 |
| <section> | 文档的独立章节 | 章节、分栏 |
| <aside> | 侧边栏内容 | 相关推荐、广告 |
| <time> | 日期和时间 | <time datetime="2026-02-22">2026年2月22日</time> |
| <mark> | 标记高亮文本 | <mark>重点内容</mark> |
| <progress> | 进度条 | <progress value="70" max="100"></progress> |
| <meter> | 度量衡显示 | <meter value="0.6">60%</meter> |
进度条示例
html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>进度条示例</title>
<style>
progress {
width: 100%;
height: 30px;
}
</style>
</head>
<body>
<h3>下载进度</h3>
<progress value="70" max="100"></progress>
<p>70%</p>
</body>
</html>
运行效果 :
显示一个进度条,70%已填充,30%未填充。
1.3 多媒体标签
HTML5最大的改进之一就是原生支持多媒体,不再需要Flash插件了。
audio标签(音频)
html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>音频播放</title>
</head>
<body>
<h3>音频播放器</h3>
<audio controls>
<source src="music.mp3" type="audio/mpeg">
<source src="music.ogg" type="audio/ogg">
您的浏览器不支持音频标签。
</audio>
</body>
</html>
属性说明 :
|----------|-------------------------|
| 属性 | 作用 |
| controls | 显示播放控制器(播放、暂停、音量等) |
| autoplay | 自动播放(可能被浏览器阻止) |
| loop | 循环播放 |
| muted | 静音 |
| preload | 预加载(auto/metadata/none) |
运行效果 :
显示一个音频播放器,包含播放、暂停、进度条、音量控制等功能。
video标签(视频)
html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>视频播放</title>
<style>
video {
width: 100%;
max-width: 600px;
}
</style>
</head>
<body>
<h3>视频播放器</h3>
<video controls poster="poster.jpg">
<source src="movie.mp4" type="video/mp4">
<source src="movie.webm" type="video/webm">
<track kind="subtitles" src="subtitles.vtt" srclang="zh" label="中文字幕">
您的浏览器不支持视频标签。
</video>
</body>
</html>
属性说明 :
|--------------|---------|
| 属性 | 作用 |
| controls | 显示播放控制器 |
| autoplay | 自动播放 |
| loop | 循环播放 |
| muted | 静音 |
| poster | 视频封面图 |
| width/height | 视频尺寸 |
运行效果 :
显示一个视频播放器,包含播放、暂停、全屏等功能。
html
注意:<source>标签用于提供多种格式的媒体文件,浏览器会选择第一个支持的格式。这样可以确保在不同浏览器上都能播放。
1.4 表单验证
HTML5新增了很多表单验证功能,大大减少了JavaScript的代码量。
新增的input类型
html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>表单验证</title>
<style>
form {
max-width: 400px;
margin: 50px auto;
padding: 20px;
border: 1px solid #ddd;
border-radius: 5px;
}
.form-group {
margin-bottom: 15px;
}
label {
display: block;
margin-bottom: 5px;
font-weight: bold;
}
input {
width: 100%;
padding: 8px;
box-sizing: border-box;
}
button {
width: 100%;
padding: 10px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
}
button:hover {
background-color: #45a049;
}
</style>
</head>
<body>
<form>
<h3>用户注册</h3>
<div class="form-group">
<label for="username">用户名:</label>
<input type="text" id="username" required minlength="3" maxlength="20" placeholder="3-20个字符">
</div>
<div class="form-group">
<label for="email">邮箱:</label>
<input type="email" id="email" required placeholder="example@domain.com">
</div>
<div class="form-group">
<label for="phone">电话:</label>
<input type="tel" id="phone" pattern="[0-9]{11}" placeholder="11位手机号">
</div>
<div class="form-group">
<label for="age">年龄:</label>
<input type="number" id="age" min="18" max="100" value="18">
</div>
<div class="form-group">
<label for="website">个人网站:</label>
<input type="url" id="website" placeholder="https://example.com">
</div>
<div class="form-group">
<label for="birthday">生日:</label>
<input type="date" id="birthday">
</div>
<div class="form-group">
<label for="time">时间:</label>
<input type="time" id="time">
</div>
<div class="form-group">
<label for="color">喜欢的颜色:</label>
<input type="color" id="color" value="#ff0000">
</div>
<div class="form-group">
<label for="range">满意度:</label>
<input type="range" id="range" min="1" max="5" value="3">
<span id="rangeValue">3</span>
</div>
<button type="submit">提交</button>
</form>
<script>
document.getElementById('range').addEventListener('input', function() {
document.getElementById('rangeValue').textContent = this.value;
});
</script>
</body>
</html>
新增的input类型 :
|--------|--------|-----------|
| 类型 | 作用 | 示例 |
| email | 邮箱地址 | 自动验证邮箱格式 |
| tel | 电话号码 | 适合手机键盘 |
| url | 网址 | 自动验证URL格式 |
| number | 数字 | 只能输入数字 |
| range | 滑块 | 选择范围内的值 |
| date | 日期 | 日期选择器 |
| time | 时间 | 时间选择器 |
| color | 颜色 | 颜色选择器 |
表单验证属性 :
|-------------|------------|
| 属性 | 作用 |
| required | 必填项 |
| minlength | 最小长度 |
| maxlength | 最大长度 |
| min | 最小值(数字/日期) |
| max | 最大值(数字/日期) |
| pattern | 正则表达式验证 |
| placeholder | 提示文本 |
运行效果 :
• 邮箱输入框会自动验证邮箱格式
• 年龄只能输入18-100的数字
• 用户名必须是3-20个字符
• 提交时,如果有必填项未填,浏览器会自动提示
1.5 HTML5 Canvas基础
Canvas是HTML5新增的绘图API,可以用JavaScript在网页上绘制图形。
Canvas基本用法
html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Canvas绘图</title>
<style>
canvas {
border: 1px solid #333;
display: block;
margin: 20px auto;
}
</style>
</head>
<body>
<canvas id="myCanvas" width="400" height="400"></canvas>
<script>
// 获取Canvas元素
let canvas = document.getElementById('myCanvas');
let ctx = canvas.getContext('2d');
// 1. 绘制矩形
ctx.fillStyle = '#ff0000';
ctx.fillRect(50, 50, 100, 100);
// 2. 绘制圆形
ctx.beginPath();
ctx.arc(250, 100, 50, 0, Math.PI * 2);
ctx.fillStyle = '#00ff00';
ctx.fill();
// 3. 绘制线条
ctx.beginPath();
ctx.moveTo(50, 250);
ctx.lineTo(150, 350);
ctx.lineTo(250, 250);
ctx.strokeStyle = '#0000ff';
ctx.lineWidth = 5;
ctx.stroke();
// 4. 绘制文字
ctx.font = '24px Arial';
ctx.fillStyle = '#333';
ctx.fillText('Hello Canvas!', 50, 380);
</script>
</body>
</html>
Canvas常用方法 :
|--------------------------|-----------|
| 方法 | 作用 |
| getContext('2d') | 获取2D绘图上下文 |
| fillRect(x, y, w, h) | 填充矩形 |
| strokeRect(x, y, w, h) | 绘制矩形边框 |
| arc(x, y, r, start, end) | 绘制圆弧/圆形 |
| beginPath() | 开始新路径 |
| moveTo(x, y) | 移动画笔 |
| lineTo(x, y) | 画线到指定点 |
| stroke() | 描边 |
| fill() | 填充 |
| fillText(text, x, y) | 绘制文字 |
运行效果 :
显示一个包含红色矩形、绿色圆形、蓝色三角形和文字的Canvas画 布。
第二部分:CSS Grid布局
CSS Grid是CSS中最强大的二维布局系统,可以轻松实现复杂的网页布局。
2.1 什么是CSS Grid?
Grid布局是二维布局系统,可以同时处理行和列。相比Flexbox的一维布局,Grid更适合处理整体布局。
对比 :
|--------|-------------|-----------|
| 特性 | Flexbox | Grid |
| 维度 | 一维(行或列) | 二维(行和列) |
| 适用场景 | 导航栏、卡片列表 | 整体布局、杂志排版 |
| 浏览器支持 | IE10+ | IE11+ |
2.2 Grid的基本概念
Grid容器 :设置了display: grid的元素
Grid项目 :容器内的直接子元素
Grid线 :构成Grid结构的水平线和垂直线
Grid线示意图
html
列线: 1 2 3 4
┌───┬───┬───┬───┐
行线1│ │ │ │ │
├───┼───┼───┼───┤
行线2│ │ │ │ │
├───┼───┼───┼───┤
行线3│ │ │ │ │
└───┴───┴───┴───┘
2.3 Grid容器属性
定义网格
css
.container {
display: grid;
/* 定义3列,每列200px */
grid-template-columns: 200px 200px 200px;
/* 或使用repeat()函数 */
grid-template-columns: repeat(3, 200px);
/* 定义2行,每行100px */
grid-template-rows: 100px 100px;
/* 使用fr单位(fraction,分数) */
grid-template-columns: 1fr 2fr 1fr; /* 1:2:1的比例 */
/* 混合使用 */
grid-template-columns: 200px 1fr 200px; /* 左右固定,中间自适应 */
}
网格间距
css
.container {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
/* 行间距 */
row-gap: 20px;
/* 列间距 */
column-gap: 20px;
/* 简写 */
gap: 20px;
}
网格对齐
css
.container {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
/* 整体水平对齐 */
justify-content: start; /* 靠左 */
justify-content: center; /* 居中 */
justify-content: end; /* 靠右 */
justify-content: space-between; /* 两端对齐 */
/* 整体垂直对齐 */
align-content: start; /* 靠上 */
align-content: center; /* 垂直居中 */
align-content: end; /* 靠下 */
align-content: space-between; /* 两端对齐 */
}
2.4 Grid项目属性
跨列和跨行
css
.item1 {
/* 跨越2列 */
grid-column: span 2;
/* 跨越2行 */
grid-row: span 2;
/* 从第1列线到第3列线 */
grid-column: 1 / 3;
/* 从第1行线到第3行线 */
grid-row: 1 / 3;
}
2.5 Grid实战示例
示例1:三栏布局
html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Grid三栏布局</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Microsoft YaHei', sans-serif;
}
.container {
display: grid;
grid-template-columns: 200px 1fr 200px;
grid-template-rows: 60px 1fr 40px;
min-height: 100vh;
}
header {
grid-column: 1 / -1; /* 跨越所有列 */
background-color: #2c3e50;
color: white;
padding: 20px;
}
aside.left {
background-color: #ecf0f1;
padding: 20px;
}
main {
background-color: #fff;
padding: 20px;
}
aside.right {
background-color: #ecf0f1;
padding: 20px;
}
footer {
grid-column: 1 / -1;
background-color: #2c3e50;
color: white;
padding: 10px;
text-align: center;
}
</style>
</head>
<body>
<div class="container">
<header>网页头部</header>
<aside class="left">左侧栏</aside>
<main>主要内容</main>
<aside class="right">右侧栏</aside>
<footer>页脚</footer>
</div>
</body>
</html>
运行效果 :
• 顶部是header,跨越所有列
• 左侧栏固定200px
• 中间内容自适应
• 右侧栏固定200px
• 底部是footer,跨越所有列
示例2:响应式网格布局
html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>响应式网格布局</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Microsoft YaHei', sans-serif;
padding: 20px;
}
.grid-container {
display: grid;
gap: 20px;
/* 默认:4列 */
grid-template-columns: repeat(4, 1fr);
}
.card {
background-color: #f0f0f0;
padding: 20px;
border-radius: 5px;
text-align: center;
}
/* 平板:3列 */
@media (max-width: 1024px) {
.grid-container {
grid-template-columns: repeat(3, 1fr);
}
}
/* 手机:2列 */
@media (max-width: 768px) {
.grid-container {
grid-template-columns: repeat(2, 1fr);
}
}
/* 小手机:1列 */
@media (max-width: 480px) {
.grid-container {
grid-template-columns: 1fr;
}
}
</style>
</head>
<body>
<div class="grid-container">
<div class="card"><h3>卡片1</h3></div>
<div class="card"><h3>卡片2</h3></div>
<div class="card"><h3>卡片3</h3></div>
<div class="card"><h3>卡片4</h3></div>
<div class="card"><h3>卡片5</h3></div>
<div class="card"><h3>卡片6</h3></div>
</div>
</body>
</html>
运行效果 :
• 电脑上:4列显示
• 平板上:3列显示
• 手机上:2列显示
• 小手机上:1列显示
第三部分:CSS动画和过渡
动画是让网页动起来的重要手段,可以提升用户体验。
3.1 CSS过渡(Transition)
过渡是指元素从一个状态平滑地过渡到另一个状态。
基本语法
css
transition: property duration timing-function delay;
|-----------------|------------------------------------------------|
| 参数 | 作用 |
| property | 要过渡的CSS属性(all/具体属性名) |
| duration | 过渡持续时间(1s/1000ms) |
| timing-function | 过渡曲线(ease/linear/ease-in/ease-out/ease-in-out) |
| delay | 延迟时间 |
过渡示例
html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>CSS过渡</title>
<style>
.box {
width: 100px;
height: 100px;
background-color: #3498db;
margin: 50px auto;
transition: all 0.5s ease;
}
.box:hover {
width: 200px;
height: 200px;
background-color: #e74c3c;
border-radius: 50%;
transform: rotate(180deg);
}
</style>
</head>
<body>
<div class="box">鼠标悬停</div>
</body>
</html>
运行效果 :
鼠标悬停时,盒子会变大、变色、变圆、旋转,所有变化都是平滑过渡 的。
3.2 CSS动画(Animation)
动画比过渡更强大,可以定义复杂的动画效果。
基本语法
css
animation: name duration timing-function delay iteration-count direction fill-mode;
|-----------------|------------------------------|
| 参数 | 作用 |
| name | 动画名称(对应@keyframes定义) |
| duration | 动画持续时间 |
| timing-function | 动画曲线 |
| delay | 延迟时间 |
| iteration-count | 迭代次数(1/infinite) |
| direction | 动画方向(normal/alternate) |
| fill-mode | 动画结束后的状态(forwards/backwards) |
定义关键帧
css
@keyframes animationName {
from {
/* 起始状态 */
}
to {
/* 结束状态 */
}
}
/* 或者使用百分比 */
@keyframes animationName {
0% {
/* 0%时的状态 */
}
50% {
/* 50%时的状态 */
}
100% {
/* 100%时的状态 */
}
}
动画示例
html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>CSS动画</title>
<style>
.box {
width: 100px;
height: 100px;
background-color: #3498db;
margin: 50px auto;
/* 应用动画 */
animation: moveAndRotate 3s ease-in-out infinite alternate;
}
/* 定义动画关键帧 */
@keyframes moveAndRotate {
0% {
transform: translateX(0) rotate(0deg);
background-color: #3498db;
}
50% {
transform: translateX(200px) rotate(180deg);
background-color: #e74c3c;
border-radius: 50%;
}
100% {
transform: translateX(400px) rotate(360deg);
background-color: #2ecc71;
}
}
</style>
</head>
<body>
<div class="box"></div>
</body>
</html>
运行效果 :
盒子会移动、旋转、变色、变圆,动画会无限循环。
3.3 实战示例:加载动画
html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>加载动画</title>
<style>
.loader {
width: 50px;
height: 50px;
border: 5px solid #f3f3f3;
border-top: 5px solid #3498db;
border-radius: 50%;
margin: 50px auto;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
</style>
</head>
<body>
<div class="loader"></div>
</body>
</html>
运行效果 :
显示一个旋转的加载图标。
第四部分:CSS变量
CSS变量(也称为自定义属性)允许你在CSS中定义变量,并在多个地方重复使用。
4.1 定义和使用CSS变量
css
:root {
/* 定义变量 */
--primary-color: #3498db;
--secondary-color: #2ecc71;
--text-color: #333;
--spacing: 20px;
}
body {
color: var(--text-color);
background-color: #f5f5f5;
padding: var(--spacing);
}
.button {
background-color: var(--primary-color);
color: white;
padding: var(--spacing);
border: none;
border-radius: 5px;
}
.button:hover {
background-color: var(--secondary-color);
}
变量命名规则 :
• 必须以--开头
• 区分大小写
• 可以包含字母、数字、下划线、连字符
4.2 CSS变量的优势
|--------|----------------------|
| 优势 | 说明 |
| 可维护性 | 修改一处,全局生效 |
| 语义化 | 变量名有意义,代码易读 |
| 动态性 | 可以用JavaScript动态修改变量值 |
4.3 JavaScript动态修改CSS变量
html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>动态CSS变量</title>
<style>
:root {
--primary-color: #3498db;
}
.box {
width: 200px;
height: 200px;
background-color: var(--primary-color);
margin: 50px auto;
transition: background-color 0.3s;
}
</style>
</head>
<body>
<div class="box"></div>
<button onclick="changeColor('red')">红色</button>
<button onclick="changeColor('green')">绿色</button>
<button onclick="changeColor('blue')">蓝色</button>
<script>
function changeColor(color) {
// 使用JavaScript修改CSS变量
document.documentElement.style.setProperty('--primary-color', color);
}
</script>
</body>
</html>
运行效果 :
点击按钮,盒子的颜色会改变。
第五部分:ES6新特性
ES6(ECMAScript 2015)是JavaScript的一个重要更新,引入了很多新特性,让代码更简洁、更易维护。
5.1 let和const
在第一篇中,我们已经学习了let和const。这里再强调一下:
javascript
// let:变量可以重新赋值
let age = 25;
age = 26; // 正确
// const:常量,不能重新赋值
const PI = 3.1415926;
PI = 3.14; // 错误:Assignment to constant variable.
// const对象/数组的属性可以修改
const person = {
name: "张三",
age: 25
};
person.age = 26; // 正确:修改对象的属性
const fruits = ["苹果", "香蕉"];
fruits.push("橙子"); // 正确:向数组添加元素
javascript
建议:优先使用const,只有需要重新赋值时才使用let。
5.2 箭头函数
箭头函数是ES6新增的一种函数定义方式,语法更简洁。
语法对比
javascript
// 传统函数
function add(a, b) {
return a + b;
}
// 箭头函数
const add = (a, b) => {
return a + b;
};
// 箭头函数简写(只有一行代码时)
const add = (a, b) => a + b;
// 没有参数时
const greet = () => {
console.log("Hello!");
};
// 只有一个参数时,可以省略括号
const square = x => x * x;
箭头函数的特点
1. 没有自己的this
javascript
const person = {
name: "张三",
// 传统函数:this指向person对象
sayHello1: function() {
console.log(this.name);
},
// 箭头函数:this指向外层作用域(window)
sayHello2: () => {
console.log(this.name);
}
};
person.sayHello1(); // "张三"
person.sayHello2(); // undefined
2. 不能用作构造函数
javascript
// 传统函数可以用作构造函数
function Person(name) {
this.name = name;
}
const p1 = new Person("张三"); // 正确
// 箭头函数不能用作构造函数
const Person2 = (name) => {
this.name = name;
};
const p2 = new Person2("李四"); // 错误:Person2 is not a constructor
javascript
建议:在回调函数、数组方法中使用箭头函数,但要小心this的问题。
5.3 模板字符串
模板字符串是用反引号(`)括起来的字符串,可以包含变量和表达式。
基本用法
javascript
const name = "张三";
const age = 25;
// 传统字符串拼接
const message1 = "我叫" + name + ",今年" + age + "岁";
// 模板字符串
const message2 = `我叫${name},今年${age}岁`;
console.log(message1); // 我叫张三,今年25岁
console.log(message2); // 我叫张三,今年25岁
多行字符串
javascript
// 传统方式:需要用\n
const text1 = "第一行\n第二行\n第三行";
// 模板字符串:直接换行
const text2 = `第一行
第二行
第三行`;
表达式插值
javascript
const a = 10;
const b = 20;
const result = `${a} + ${b} = ${a + b}`;
console.log(result); // 10 + 20 = 30
5.4 解构赋值
解构赋值可以从数组或对象中提取值,赋给变量。
数组解构
javascript
const fruits = ["苹果", "香蕉", "橙子"];
// 传统方式
const fruit1 = fruits[0];
const fruit2 = fruits[1];
const fruit3 = fruits[2];
// 解构赋值
const [f1, f2, f3] = fruits;
console.log(f1); // "苹果"
console.log(f2); // "香蕉"
console.log(f3); // "橙子"
// 跳过某些值
const [first, , third] = fruits;
console.log(first); // "苹果"
console.log(third); // "橙子"
对象解构
javascript
const person = {
name: "张三",
age: 25,
city: "北京"
};
// 传统方式
const name = person.name;
const age = person.age;
const city = person.city;
// 解构赋值
const { name, age, city } = person;
console.log(name); // "张三"
console.log(age); // 25
console.log(city); // "北京"
// 重命名
const { name: userName, age: userAge } = person;
console.log(userName); // "张三"
console.log(userAge); // 25
函数参数解构
javascript
// 函数参数解构
function greet({ name, age }) {
console.log(`你好,${name}!你今年${age}岁了。`);
}
const person = {
name: "张三",
age: 25
};
greet(person); // 你好,张三!你今年25岁了。
5.5 数组新增方法
forEach
遍历数组,对每个元素执行操作。
javascript
const fruits = ["苹果", "香蕉", "橙子"];
fruits.forEach(function(fruit, index) {
console.log(`${index}: ${fruit}`);
});
// 输出:
// 0: 苹果
// 1: 香蕉
// 2: 橙子
map
创建一个新数组,新数组的每个元素是原数组元素经过函数处理后的值。
javascript
const numbers = [1, 2, 3, 4, 5];
// 所有元素乘以2
const doubled = numbers.map(x => x * 2);
console.log(doubled); // [2, 4, 6, 8, 10]
// 提取对象的某个属性
const users = [
{ name: "张三", age: 25 },
{ name: "李四", age: 30 }
];
const names = users.map(user => user.name);
console.log(names); // ["张三", "李四"]
filter
创建一个新数组,只包含满足条件的元素。
javascript
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// 筛选偶数
const evens = numbers.filter(x => x % 2 === 0);
console.log(evens); // [2, 4, 6, 8, 10]
// 筛选大于5的数
const greaterThan5 = numbers.filter(x => x > 5);
console.log(greaterThan5); // [6, 7, 8, 9, 10]
reduce
将数组所有元素通过函数合并成一个值。
javascript
const numbers = [1, 2, 3, 4, 5];
// 计算总和
const sum = numbers.reduce((acc, curr) => acc + curr, 0);
console.log(sum); // 15
// 计算乘积
const product = numbers.reduce((acc, curr) => acc * curr, 1);
console.log(product); // 120
// 查找最大值
const max = numbers.reduce((acc, curr) => Math.max(acc, curr), 0);
console.log(max); // 5
reduce的参数 :
|--------------|-------------|
| 参数 | 说明 |
| acc | 累加器(上一次的结果) |
| curr | 当前元素 |
| initialValue | 初始值(可选) |
链式调用
多个数组方法可以链式调用。
javascript
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// 筛选偶数,乘以2,求和
const result = numbers
.filter(x => x % 2 === 0)
.map(x => x * 2)
.reduce((acc, curr) => acc + curr, 0);
console.log(result); // 60
// 分解:
// filter: [2, 4, 6, 8, 10]
// map: [4, 8, 12, 16, 20]
// reduce: 60
第六部分:DOM事件详解
在第一篇中,我们学习了DOM操作。现在我们来深入学习DOM事件。
6.1 事件监听
addEventListener
addEventListener是添加事件监听器的标准方法。
javascript
// 获取元素
const button = document.getElementById('myButton');
// 添加事件监听器
button.addEventListener('click', function(event) {
console.log('按钮被点击了!');
});
语法 :
javascript
element.addEventListener(event, function, useCapture);
|------------|------------------------|
| 参数 | 说明 |
| event | 事件类型(click、mouseover等) |
| function | 事件处理函数 |
| useCapture | 是否在捕获阶段触发(默认false) |
移除事件监听器
javascript
// 定义事件处理函数
function handleClick(event) {
console.log('按钮被点击了!');
}
// 添加事件监听器
button.addEventListener('click', handleClick);
// 移除事件监听器
button.removeEventListener('click', handleClick);
javascript
注意:移除事件监听器时,函数必须是同一个。
6.2 常用事件类型
鼠标事件
|------------|--------|
| 事件 | 说明 |
| click | 点击 |
| dblclick | 双击 |
| mouseover | 鼠标移入 |
| mouseout | 鼠标移出 |
| mouseenter | 鼠标进入 |
| mouseleave | 鼠标离开 |
| mousedown | 鼠标按下 |
| mouseup | 鼠标松开 |
| mousemove | 鼠标移动 |
javascript
const box = document.getElementById('myBox');
box.addEventListener('click', function() {
console.log('点击');
});
box.addEventListener('mouseover', function() {
console.log('鼠标移入');
});
box.addEventListener('mouseout', function() {
console.log('鼠标移出');
});
键盘事件
|----------|-----------------------|
| 事件 | 说明 |
| keydown | 按下键盘 |
| keyup | 松开键盘 |
| keypress | 按下字符键(已废弃,建议用keydown) |
javascript
document.addEventListener('keydown', function(event) {
console.log('按键:', event.key);
console.log('按键代码:', event.keyCode);
// 按下Enter键
if (event.key === 'Enter') {
console.log('你按下了Enter键');
}
});
表单事件
|--------|------------|
| 事件 | 说明 |
| submit | 提交表单 |
| change | 表单元素值改变 |
| input | 输入框值改变(实时) |
| focus | 获得焦点 |
| blur | 失去焦点 |
javascript
const input = document.getElementById('myInput');
input.addEventListener('input', function(event) {
console.log('输入值:', this.value);
});
input.addEventListener('focus', function() {
console.log('获得焦点');
});
input.addEventListener('blur', function() {
console.log('失去焦点');
});
窗口事件
|--------------|--------|
| 事件 | 说明 |
| load | 页面加载完成 |
| resize | 窗口大小改变 |
| scroll | 页面滚动 |
| beforeunload | 页面即将关闭 |
javascript
window.addEventListener('load', function() {
console.log('页面加载完成');
});
window.addEventListener('resize', function() {
console.log('窗口大小改变');
});
window.addEventListener('scroll', function() {
console.log('页面滚动');
});
6.3 事件对象
事件处理函数接收一个事件对象作为参数。
javascript
button.addEventListener('click', function(event) {
console.log('事件对象:', event);
});
常用属性 :
|-------------------------|------------|
| 属性 | 说明 |
| event.type | 事件类型 |
| event.target | 触发事件的元素 |
| event.currentTarget | 绑定事件的元素 |
| event.clientX/Y | 鼠标坐标(相对视口) |
| event.pageX/Y | 鼠标坐标(相对文档) |
| event.key | 按键值 |
| event.keyCode | 按键代码 |
| event.preventDefault() | 阻止默认行为 |
| event.stopPropagation() | 阻止事件冒泡 |
示例:阻止默认行为
html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>阻止默认行为</title>
</head>
<body>
<a href="https://www.csdn.net" id="myLink">点击我(不会跳转)</a>
<form id="myForm">
<input type="text" required>
<button type="submit">提交(不会提交)</button>
</form>
<script>
// 阻止链接跳转
document.getElementById('myLink').addEventListener('click', function(event) {
event.preventDefault();
console.log('链接被点击,但不会跳转');
});
// 阻止表单提交
document.getElementById('myForm').addEventListener('submit', function(event) {
event.preventDefault();
console.log('表单提交被阻止');
});
</script>
</body>
</html>
运行效果 :
• 点击链接不会跳转
• 提交表单不会刷新页面
6.4 事件冒泡和捕获
事件冒泡
事件从最具体的元素开始,向上传播到父元素。
html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
.outer {
width: 200px;
height: 200px;
background-color: #f00;
padding: 20px;
}
.inner {
width: 100px;
height: 100px;
background-color: #0f0;
}
</style>
</head>
<body>
<div class="outer" id="outer">
外层元素
<div class="inner" id="inner">内层元素</div>
</div>
<script>
document.getElementById('inner').addEventListener('click', function() {
console.log('内层元素被点击');
});
document.getElementById('outer').addEventListener('click', function() {
console.log('外层元素被点击');
});
// 点击内层元素,输出:
// 内层元素被点击
// 外层元素被点击
</script>
</body>
</html>
阻止事件冒泡
javascript
document.getElementById('inner').addEventListener('click', function(event) {
event.stopPropagation(); // 阻止事件冒泡
console.log('内层元素被点击');
});
// 点击内层元素,只输出:
// 内层元素被点击
事件委托
利用事件冒泡,在父元素上监听事件,而不是在每个子元素上都绑定事件。
html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
ul {
list-style: none;
padding: 0;
}
li {
padding: 10px;
background-color: #f0f0f0;
margin: 5px 0;
cursor: pointer;
}
li:hover {
background-color: #ddd;
}
</style>
</head>
<body>
<ul id="myList">
<li>项目1</li>
<li>项目2</li>
<li>项目3</li>
</ul>
<script>
// 事件委托:在父元素上监听点击事件
document.getElementById('myList').addEventListener('click', function(event) {
// 检查点击的是否是li元素
if (event.target.tagName === 'LI') {
console.log('你点击了:', event.target.textContent);
}
});
</script>
</body>
</html>
优势 :
• 减少事件监听器的数量
• 动态添加的元素也能触发事件
• 提高性能
第七部分:异步编程基础
JavaScript是单线程的,但很多时候需要处理异步操作(如网络请求、定时器等)。
7.1 同步和异步
同步代码
代码按顺序执行,上一行代码执行完毕,才会执行下一行。
javascript
console.log('1');
console.log('2');
console.log('3');
// 输出:1 2 3
异步代码
代码不会立即执行,而是等到某个事件发生后才执行。
javascript
console.log('1');
setTimeout(function() {
console.log('2');
}, 1000); // 1秒后执行
console.log('3');
// 输出:1 3 2
7.2 回调函数
回调函数是异步编程的基础。
javascript
function doSomething(callback) {
console.log('开始执行');
setTimeout(function() {
console.log('异步操作完成');
callback(); // 执行回调函数
}, 1000);
}
doSomething(function() {
console.log('回调函数被调用');
});
// 输出:
// 开始执行
// (1秒后)
// 异步操作完成
// 回调函数被调用
回调地狱
多个异步操作嵌套时,会产生"回调地狱"。
javascript
setTimeout(function() {
console.log('第一步');
setTimeout(function() {
console.log('第二步');
setTimeout(function() {
console.log('第三步');
}, 1000);
}, 1000);
}, 1000);
这种代码可读性很差,难以维护。
7.3 Promise
Promise是ES6引入的,用于解决回调地狱的问题。
基本用法
javascript
const promise = new Promise(function(resolve, reject) {
// 异步操作
setTimeout(function() {
// 成功
const success = true;
if (success) {
resolve('操作成功');
} else {
reject('操作失败');
}
}, 1000);
});
// 处理结果
promise.then(function(result) {
console.log(result); // 操作成功
}).catch(function(error) {
console.log(error); // 操作失败
});
Promise的三种状态 :
|-----------|--------|
| 状态 | 说明 |
| pending | 等待中 |
| fulfilled | 已成功 |
| rejected | 已失败 |
then和catch
javascript
const promise = new Promise(function(resolve, reject) {
setTimeout(function() {
resolve('数据加载成功');
}, 1000);
});
promise
.then(function(result) {
console.log(result);
return '第一步完成';
})
.then(function(result) {
console.log(result);
return '第二步完成';
})
.then(function(result) {
console.log(result);
})
.catch(function(error) {
console.log(error);
});
Promise链式调用
javascript
function step1() {
return new Promise(function(resolve) {
setTimeout(function() {
console.log('第一步完成');
resolve();
}, 1000);
});
}
function step2() {
return new Promise(function(resolve) {
setTimeout(function() {
console.log('第二步完成');
resolve();
}, 1000);
});
}
function step3() {
return new Promise(function(resolve) {
setTimeout(function() {
console.log('第三步完成');
resolve();
}, 1000);
});
}
// 链式调用
step1()
.then(step2)
.then(step3)
.then(function() {
console.log('所有步骤完成');
});
7.4 async/await
async/await是ES8引入的,让异步代码看起来像同步代码。
基本用法
javascript
function delay(ms) {
return new Promise(function(resolve) {
setTimeout(resolve, ms);
});
}
async function doSomething() {
console.log('开始');
await delay(1000); // 等待1秒
console.log('第一步');
await delay(1000); // 等待1秒
console.log('第二步');
await delay(1000); // 等待1秒
console.log('第三步');
console.log('完成');
}
doSomething();
错误处理
javascript
async function fetchData() {
try {
const result = await fetch('/api/data');
const data = await result.json();
console.log(data);
} catch (error) {
console.error('出错了:', error);
}
}
fetchData();
对比回调函数和Promise和async/await
javascript
// 回调函数
setTimeout(function() {
console.log('完成');
}, 1000);
// Promise
new Promise(function(resolve) {
setTimeout(resolve, 1000);
}).then(function() {
console.log('完成');
});
// async/await
(async function() {
await new Promise(function(resolve) {
setTimeout(resolve, 1000);
});
console.log('完成');
})();
第八部分:综合实战项目
让我们把今天学到的所有知识综合起来,做一个完整的项目。
实战项目:待办事项管理器
功能需求 :
-
添加待办事项
-
标记完成/未完成
-
删除待办事项
-
数据持久化(localStorage)
-
搜索过滤
-
动画效果
-
响应式设计
html
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>待办事项管理器</title>
<style>
:root {
--primary-color: #3498db;
--success-color: #2ecc71;
--danger-color: #e74c3c;
--text-color: #333;
--bg-color: #f5f5f5;
--card-bg: #fff;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Microsoft YaHei', sans-serif;
background-color: var(--bg-color);
color: var(--text-color);
padding: 20px;
}
.container {
max-width: 600px;
margin: 0 auto;
}
h1 {
text-align: center;
color: var(--primary-color);
margin-bottom: 30px;
}
/* 输入区域 */
.input-group {
display: flex;
gap: 10px;
margin-bottom: 20px;
}
input[type="text"] {
flex: 1;
padding: 10px;
border: 2px solid #ddd;
border-radius: 5px;
font-size: 16px;
}
input[type="text"]:focus {
outline: none;
border-color: var(--primary-color);
}
button {
padding: 10px 20px;
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 16px;
transition: all 0.3s;
}
.add-btn {
background-color: var(--primary-color);
color: white;
}
.add-btn:hover {
background-color: #2980b9;
}
/* 搜索框 */
.search-group {
margin-bottom: 20px;
}
.search-group input {
width: 100%;
}
/* 统计信息 */
.stats {
display: flex;
justify-content: space-around;
margin-bottom: 20px;
}
.stat-item {
text-align: center;
}
.stat-item strong {
font-size: 24px;
color: var(--primary-color);
}
/* 待办事项列表 */
.todo-list {
list-style: none;
}
.todo-item {
background-color: var(--card-bg);
padding: 15px;
margin-bottom: 10px;
border-radius: 5px;
display: flex;
align-items: center;
gap: 10px;
transition: all 0.3s;
animation: slideIn 0.3s ease-out;
}
@keyframes slideIn {
from {
opacity: 0;
transform: translateX(-20px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
.todo-item.completed {
opacity: 0.6;
}
.todo-item.completed .todo-text {
text-decoration: line-through;
color: #999;
}
.todo-checkbox {
width: 20px;
height: 20px;
cursor: pointer;
}
.todo-text {
flex: 1;
font-size: 16px;
}
.todo-date {
font-size: 12px;
color: #999;
}
.todo-actions {
display: flex;
gap: 5px;
}
.delete-btn {
background-color: var(--danger-color);
color: white;
padding: 5px 10px;
font-size: 14px;
}
.delete-btn:hover {
background-color: #c0392b;
}
/* 空状态 */
.empty-state {
text-align: center;
color: #999;
padding: 40px 0;
}
/* 响应式设计 */
@media (max-width: 480px) {
.input-group {
flex-direction: column;
}
.add-btn {
width: 100%;
}
}
</style>
</head>
<body>
<div class="container">
<h1>待办事项管理器</h1>
<!-- 输入区域 -->
<div class="input-group">
<input type="text" id="todoInput" placeholder="输入待办事项...">
<button class="add-btn" onclick="addTodo()">添加</button>
</div>
<!-- 搜索框 -->
<div class="search-group">
<input type="text" id="searchInput" placeholder="搜索待办事项...">
</div>
<!-- 统计信息 -->
<div class="stats">
<div class="stat-item">
<strong id="totalCount">0</strong>
<div>总计</div>
</div>
<div class="stat-item">
<strong id="completedCount">0</strong>
<div>已完成</div>
</div>
<div class="stat-item">
<strong id="pendingCount">0</strong>
<div>未完成</div>
</div>
</div>
<!-- 待办事项列表 -->
<ul class="todo-list" id="todoList"></ul>
</div>
<script>
// 存储待办事项的数组
let todos = [];
// 页面加载时,从localStorage读取数据
window.addEventListener('load', function() {
const savedTodos = localStorage.getItem('todos');
if (savedTodos) {
todos = JSON.parse(savedTodos);
}
renderTodos();
});
// 添加待办事项
function addTodo() {
const input = document.getElementById('todoInput');
const text = input.value.trim();
if (text === '') {
alert('请输入待办事项!');
return;
}
const todo = {
id: Date.now(),
text: text,
completed: false,
date: new Date().toLocaleString()
};
todos.unshift(todo); // 添加到数组开头
saveTodos();
renderTodos();
input.value = ''; // 清空输入框
input.focus(); // 聚焦输入框
}
// 切换完成状态
function toggleComplete(id) {
const todo = todos.find(t => t.id === id);
if (todo) {
todo.completed = !todo.completed;
saveTodos();
renderTodos();
}
}
// 删除待办事项
function deleteTodo(id) {
if (confirm('确定要删除这个待办事项吗?')) {
todos = todos.filter(t => t.id !== id);
saveTodos();
renderTodos();
}
}
// 保存到localStorage
function saveTodos() {
localStorage.setItem('todos', JSON.stringify(todos));
}
// 渲染待办事项列表
function renderTodos() {
const list = document.getElementById('todoList');
const searchText = document.getElementById('searchInput').value.toLowerCase();
// 过滤
let filteredTodos = todos.filter(todo => {
return todo.text.toLowerCase().includes(searchText);
});
// 排序:未完成在前,已完成在后
filteredTodos.sort((a, b) => {
if (a.completed === b.completed) {
return b.id - a.id; // 按创建时间倒序
}
return a.completed ? 1 : -1;
});
// 清空列表
list.innerHTML = '';
// 生成列表项
if (filteredTodos.length === 0) {
list.innerHTML = '<li class="empty-state">暂无待办事项</li>';
} else {
filteredTodos.forEach(todo => {
const li = document.createElement('li');
li.className = 'todo-item' + (todo.completed ? ' completed' : '');
li.innerHTML = `
<input type="checkbox" class="todo-checkbox"
${todo.completed ? 'checked' : ''}
onchange="toggleComplete(${todo.id})">
<div>
<div class="todo-text">${escapeHtml(todo.text)}</div>
<div class="todo-date">${todo.date}</div>
</div>
<div class="todo-actions">
<button class="delete-btn" onclick="deleteTodo(${todo.id})">删除</button>
</div>
`;
list.appendChild(li);
});
}
// 更新统计信息
updateStats();
}
// 更新统计信息
function updateStats() {
document.getElementById('totalCount').textContent = todos.length;
document.getElementById('completedCount').textContent =
todos.filter(t => t.completed).length;
document.getElementById('pendingCount').textContent =
todos.filter(t => !t.completed).length;
}
// 转义HTML(防止XSS攻击)
function escapeHtml(text) {
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
// 搜索功能
document.getElementById('searchInput').addEventListener('input', renderTodos);
// 回车键添加
document.getElementById('todoInput').addEventListener('keypress', function(event) {
if (event.key === 'Enter') {
addTodo();
}
});
</script>
</body>
</html>
代码解析 :
|--------------------|-------------------|
| 代码部分 | 作用 |
| :root | 定义CSS变量(主题颜色) |
| @keyframes slideIn | 定义滑入动画 |
| localStorage | 本地存储,数据持久化 |
| renderTodos() | 渲染待办事项列表 |
| saveTodos() | 保存数据到localStorage |
| escapeHtml() | 防止XSS攻击 |
| filter() | 过滤待办事项 |
| sort() | 排序待办事项 |
| addEventListener() | 事件监听 |
功能说明 :
-
添加待办事项 :输入文字,点击"添加"按钮,或按回车键
-
标记完成 :勾选复选框,待办事项会被标记为完成,文字会添加删 除线
-
删除待办事项 :点击"删除"按钮,删除对应的待办事项
-
搜索过滤 :在搜索框输入文字,列表会实时过滤
-
数据持久化 :刷新页面后,待办事项不会丢失(使用 localStorage)
-
动画效果 :添加待办事项时有滑入动画
-
响应式设计 :在手机上也能正常使用
-
统计信息 :实时显示总计、已完成、未完成的数量
本篇知识总结
这篇作为系列教程的第三篇,也是完结篇,我们学习了高级的前端知识。
HTML部分
|----------|---------------------------------------------|
| 知识点 | 内容 |
| HTML5新特性 | 语义化标签、多媒体标签、表单验证、Canvas |
| audio标签 | 音频播放器 |
| video标签 | 视频播放器 |
| 表单验证 | 新增input类型(email、tel、url等)、验证属性 |
| Canvas | 绘图API(fillRect、arc、beginPath、moveTo、lineTo) |
CSS部分
|---------|--------------------------------------------------------|
| 知识点 | 内容 |
| Grid布局 | 二维布局系统、grid-template-columns、grid-template-rows |
| Grid属性 | gap、grid-column、grid-row、justify-content、align-content |
| CSS过渡 | transition、transition-property、transition-duration |
| CSS动画 | animation、@keyframes、animation-name、animation-duration |
| CSS变量 | :root、var()、动态修改 |
JavaScript部分
|-----------|---------------------------------|
| 知识点 | 内容 |
| let和const | 变量声明、作用域 |
| 箭头函数 | 简洁语法、this绑定 |
| 模板字符串 | 反引号、变量插值、多行字符串 |
| 解构赋值 | 数组解构、对象解构、函数参数解构 |
| 数组方法 | forEach、map、filter、reduce、链式调用 |
| DOM事件 | addEventListener、事件对象、事件冒泡、事件委托 |
| 异步编程 | 回调函数、Promise、async/await |
系列教程总结
经过三篇教程的学习,我们已经系统掌握了前端开发的核心技术。
知识体系回顾
第一篇:认识工具
• HTML:网页的骨架(h1-h6、p、a、img、div、span、ul/li)
• CSS:网页的颜值(选择器、属性、样式)
• JavaScript:网页的大脑(变量、数据类型、函数、DOM操作)
• 三者配合:综合实战案例
第二篇:学习使用工具的方法
• HTML进阶:表格、表单、属性、语义化标签
• CSS进阶:盒模型、Flexbox布局、响应式设计
• JavaScript进阶:运算符、条件语句、循环语句、数组、对象
• 综合实战:学生成绩管理系统
第三篇:学习高级技巧
• HTML5:多媒体标签、表单验证、Canvas
• CSS:Grid布局、动画、变量
• JavaScript:ES6新特性、DOM事件、异步编程
• 综合实战:待办事项管理器
学习路径建议
html
第一步:掌握基础(第一篇)
↓
第二步:深入学习(第二篇)
↓
第三步:提升技能(第三篇)
↓
第四步:学习框架(React、Vue、Angular)
↓
第五步:学习工程化(Webpack、Vite)
↓
第六步:实战项目
↓
第七步:持续学习,跟上技术发展
接下来可以学习什么?
前端框架 :
• Vue.js(易学易用,适合新手)
• React(生态完善,就业需求大)
• Angular(企业级项目)
前端工程化 :
• Webpack(模块打包工具)
• Vite(新一代构建工具)
• npm/yarn(包管理器)
TypeScript :
• JavaScript的超集,添加了类型系统
• 提高代码可维护性
• 大型项目必备
前端优化 :
• 性能优化
• SEO优化
• 用户体验优化
学习建议
1. 不要急于求成
前端知识体系很庞大,不要想一口气学完。先打好基础,再逐步深入。
建议 :
• 学完本系列教程后,做一些小项目巩固
• 熟练掌握基础知识后,再学习框架
• 多看优秀的开源项目,学习最佳实践
2. 多动手,多实践
编程是一项技能,不是知识。看懂了不代表学会了。
建议 :
• 每个知识点都亲自写代码测试
• 做一些完整的项目
• 遇到问题,自己先思考,再查资料
结语
恭喜你完成了整个系列教程的学习!
通过这三篇文章,我们从零开始,系统学习了HTML、CSS、JavaScript的核心技术:
• 第一篇 :认识了前端开发的三大技术,了解了它们各自的作用
• 第二篇 :深入学习了实用的知识点(表格、表单、盒模型、Flexbox、响应 式设计、循环、数组、对象)
• 第三篇 :掌握了高级技巧(HTML5、Grid、动画、ES6、DOM事件、异步编 程)
这三篇文章涵盖了一个前端工程师需要掌握的基础知识体系。
但学习永无止境。
前端技术发展很快,新的框架、新的工具、新的技术不断涌现。你需要持续学习,跟上技术发展的步伐。
记住几个核心原则:
-
打好基础 :基础不牢,地动山摇
-
多动手实践 :看懂了不代表学会了
-
持续学习 :技术更新很快,不能停下脚步
-
培养编程思维 :编程不仅仅是写代码,更是解决问题
最后的最后 :
前端开发是一门很有趣的技术。你可以用代码创造出漂亮的网页,实现各种交互效果,给用户带来良好的体验。
希望这三篇文章能帮你打下坚实的基础,开启你的前端开发之旅。
如果你在学习过程中遇到问题,欢迎在评论区留言。我会尽力解答。
祝你在前端开发的道路上越走越远!
附录:完整知识体系图
html
前端开发知识体系
│
├─ HTML(结构层)
│ ├─ 基础标签(h1-h6、p、a、img、div、span、ul/li)
│ ├─ 进阶标签(table、form、input、select、textarea)
│ ├─ 语义化标签(header、nav、main、article、section、aside、footer)
│ ├─ HTML5特性(audio、video、Canvas、表单验证)
│ └─ HTML属性(id、class、href、src、style、title、alt)
│
├─ CSS(表现层)
│ ├─ 基础样式(color、font-size、background、border、margin、padding)
│ ├─ 选择器(标签选择器、类选择器、id选择器、属性选择器、伪类)
│ ├─ 盒模型(content、padding、border、margin、box-sizing)
│ ├─ 布局(Flexbox、Grid、position、float)
│ ├─ 响应式设计(@media、viewport、相对单位)
│ ├─ 动画(transition、animation、@keyframes)
│ └─ CSS变量(:root、var())
│
└─ JavaScript(行为层)
├─ 基础语法(变量、数据类型、运算符)
├─ 流程控制(条件语句、循环语句)
├─ 函数(定义、调用、箭头函数、作用域)
├─ 数组(创建、遍历、方法:forEach、map、filter、reduce)
├─ 对象(创建、属性、方法、JSON)
├─ DOM操作(获取元素、修改内容、修改样式)
├─ 事件(addEventListener、事件对象、事件冒泡、事件委托)
├─ ES6新特性(let/const、模板字符串、解构赋值、类、模块)
└─ 异步编程(回调函数、Promise、async/await)
版权声明 :
本文为原创文章,转载请注明出处。未经作者许可,禁止用于商业用途。