前言

        前两篇我们打好了基础,这一篇我们就要"起飞"了。我们会学习更多高级、更现代、更实用的知识点。

按照之前的"房子装修"比喻:

        • 第一篇是认识工具(结构、装修、智能系统)

        • 第二篇是学习使用工具的方法(表格、表单、盒模型、布局、循环)

        • 这一篇是学习高级技巧(多媒体、网格布局、动画、现代语法、事件处理、 异步编程)

准备好了吗?让我们开始这趟精彩的进阶之旅吧!

第一部分: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>

进度条示例
<!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标签(音频)
<!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标签(视频)
<!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

视频尺寸

        运行效果

显示一个视频播放器,包含播放、暂停、全屏等功能。

注意:<source>标签用于提供多种格式的媒体文件,浏览器会选择第一个支持的格式。这样可以确保在不同浏览器上都能播放。

1.4 表单验证

        HTML5新增了很多表单验证功能,大大减少了JavaScript的代码量。

新增的input类型
<!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基本用法
<!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线示意图
列线:  1   2   3   4
     ┌───┬───┬───┬───┐
行线1│   │   │   │   │
     ├───┼───┼───┼───┤
行线2│   │   │   │   │
     ├───┼───┼───┼───┤
行线3│   │   │   │   │
     └───┴───┴───┴───┘

2.3 Grid容器属性

定义网格
.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;  /* 左右固定,中间自适应 */
}
网格间距
.container {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  /* 行间距 */
  row-gap: 20px;
  /* 列间距 */
  column-gap: 20px;
  /* 简写 */
  gap: 20px;
}
网格对齐
.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项目属性

跨列和跨行
.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:三栏布局
<!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:响应式网格布局
<!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)

        过渡是指元素从一个状态平滑地过渡到另一个状态。

基本语法
transition: property duration timing-function delay;

参数

作用

property

要过渡的CSS属性(all/具体属性名)

duration

过渡持续时间(1s/1000ms)

timing-function

过渡曲线(ease/linear/ease-in/ease-out/ease-in-out)

delay

延迟时间

过渡示例
<!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)

        动画比过渡更强大,可以定义复杂的动画效果。

基本语法
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)

定义关键帧
@keyframes animationName {
  from {
    /* 起始状态 */
  }
  to {
    /* 结束状态 */
  }
}
/* 或者使用百分比 */
@keyframes animationName {
  0% {
    /* 0%时的状态 */
  }
  50% {
    /* 50%时的状态 */
  }
  100% {
    /* 100%时的状态 */
  }
}
动画示例
<!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 实战示例:加载动画

<!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变量

: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变量

<!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

        在第一篇中,我们已经学习了letconst。这里再强调一下:

// 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("橙子");  // 正确:向数组添加元素
        建议:优先使用const,只有需要重新赋值时才使用let。

5.2 箭头函数

        箭头函数是ES6新增的一种函数定义方式,语法更简洁。

语法对比
// 传统函数
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

const person = {
  name: "张三",
  // 传统函数:this指向person对象
  sayHello1: function() {
    console.log(this.name);
  },
  // 箭头函数:this指向外层作用域(window)
  sayHello2: () => {
    console.log(this.name);
  }
};
person.sayHello1();  // "张三"
person.sayHello2();  // undefined

        2. 不能用作构造函数

// 传统函数可以用作构造函数
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
建议:在回调函数、数组方法中使用箭头函数,但要小心this的问题。

5.3 模板字符串

        模板字符串是用反引号(`)括起来的字符串,可以包含变量和表达式。

基本用法
const name = "张三";
const age = 25;
// 传统字符串拼接
const message1 = "我叫" + name + ",今年" + age + "岁";
// 模板字符串
const message2 = `我叫${name},今年${age}岁`;
console.log(message1);  // 我叫张三,今年25岁
console.log(message2);  // 我叫张三,今年25岁
多行字符串
// 传统方式:需要用\n
const text1 = "第一行\n第二行\n第三行";
// 模板字符串:直接换行
const text2 = `第一行
第二行
第三行`;
表达式插值
const a = 10;
const b = 20;
const result = `${a} + ${b} = ${a + b}`;
console.log(result);  // 10 + 20 = 30

5.4 解构赋值

        解构赋值可以从数组或对象中提取值,赋给变量。

数组解构
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);  // "橙子"
对象解构
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
函数参数解构
// 函数参数解构
function greet({ name, age }) {
  console.log(`你好,${name}!你今年${age}岁了。`);
}
const person = {
  name: "张三",
  age: 25
};
greet(person);  // 你好,张三!你今年25岁了。

5.5 数组新增方法

forEach

        遍历数组,对每个元素执行操作。

const fruits = ["苹果", "香蕉", "橙子"];
fruits.forEach(function(fruit, index) {
  console.log(`${index}: ${fruit}`);
});
// 输出:
// 0: 苹果
// 1: 香蕉
// 2: 橙子
map

        创建一个新数组,新数组的每个元素是原数组元素经过函数处理后的值。

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

        创建一个新数组,只包含满足条件的元素。

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

        将数组所有元素通过函数合并成一个值。

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

初始值(可选)

链式调用

        多个数组方法可以链式调用。

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是添加事件监听器的标准方法。

// 获取元素
const button = document.getElementById('myButton');
// 添加事件监听器
button.addEventListener('click', function(event) {
  console.log('按钮被点击了!');
});

语法

element.addEventListener(event, function, useCapture);

参数

说明

event

事件类型(click、mouseover等)

function

事件处理函数

useCapture

是否在捕获阶段触发(默认false)

移除事件监听器
// 定义事件处理函数
function handleClick(event) {
  console.log('按钮被点击了!');
}
// 添加事件监听器
button.addEventListener('click', handleClick);
// 移除事件监听器
button.removeEventListener('click', handleClick);
注意:移除事件监听器时,函数必须是同一个。

6.2 常用事件类型

鼠标事件

事件

说明

click

点击

dblclick

双击

mouseover

鼠标移入

mouseout

鼠标移出

mouseenter

鼠标进入

mouseleave

鼠标离开

mousedown

鼠标按下

mouseup

鼠标松开

mousemove

鼠标移动

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)

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

失去焦点

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

页面即将关闭

window.addEventListener('load', function() {
  console.log('页面加载完成');
});
window.addEventListener('resize', function() {
  console.log('窗口大小改变');
});
window.addEventListener('scroll', function() {
  console.log('页面滚动');
});

6.3 事件对象

        事件处理函数接收一个事件对象作为参数。

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()

阻止事件冒泡

示例:阻止默认行为
<!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 事件冒泡和捕获

事件冒泡

        事件从最具体的元素开始,向上传播到父元素。

<!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>
阻止事件冒泡
document.getElementById('inner').addEventListener('click', function(event) {
  event.stopPropagation();  // 阻止事件冒泡
  console.log('内层元素被点击');
});
// 点击内层元素,只输出:
// 内层元素被点击
事件委托

利用事件冒泡,在父元素上监听事件,而不是在每个子元素上都绑定事件。

<!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 同步和异步

同步代码

        代码按顺序执行,上一行代码执行完毕,才会执行下一行。

console.log('1');
console.log('2');
console.log('3');
// 输出:1 2 3
异步代码

        代码不会立即执行,而是等到某个事件发生后才执行。

console.log('1');
setTimeout(function() {
  console.log('2');
}, 1000);  // 1秒后执行
console.log('3');
// 输出:1 3 2

7.2 回调函数

        回调函数是异步编程的基础。

function doSomething(callback) {
  console.log('开始执行');
  setTimeout(function() {
    console.log('异步操作完成');
    callback();  // 执行回调函数
  }, 1000);
}
doSomething(function() {
  console.log('回调函数被调用');
});
// 输出:
// 开始执行
// (1秒后)
// 异步操作完成
// 回调函数被调用
回调地狱

        多个异步操作嵌套时,会产生"回调地狱"。

setTimeout(function() {
  console.log('第一步');
  setTimeout(function() {
    console.log('第二步');
    setTimeout(function() {
      console.log('第三步');
    }, 1000);
  }, 1000);
}, 1000);

        这种代码可读性很差,难以维护。

7.3 Promise

        Promise是ES6引入的,用于解决回调地狱的问题。

基本用法
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
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链式调用
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引入的,让异步代码看起来像同步代码。

基本用法
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();
错误处理
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
// 回调函数
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('完成');
})();

第八部分:综合实战项目

        让我们把今天学到的所有知识综合起来,做一个完整的项目。

实战项目:待办事项管理器

        功能需求

        1. 添加待办事项

        2. 标记完成/未完成

        3. 删除待办事项

        4. 数据持久化(localStorage)

        5. 搜索过滤

        6. 动画效果

        7. 响应式设计

<!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()

事件监听

        功能说明

8. 添加待办事项:输入文字,点击"添加"按钮,或按回车键

9. 标记完成:勾选复选框,待办事项会被标记为完成,文字会添加删 除线

10. 删除待办事项:点击"删除"按钮,删除对应的待办事项

11. 搜索过滤:在搜索框输入文字,列表会实时过滤

12. 数据持久化:刷新页面后,待办事项不会丢失(使用 localStorage)

13. 动画效果:添加待办事项时有滑入动画

14. 响应式设计:在手机上也能正常使用

15. 统计信息:实时显示总计、已完成、未完成的数量

本篇知识总结

        这篇作为系列教程的第三篇,也是完结篇,我们学习了高级的前端知识。

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事件、异步编程

综合实战:待办事项管理器

学习路径建议

第一步:掌握基础(第一篇)
  ↓
第二步:深入学习(第二篇)
  ↓
第三步:提升技能(第三篇)
  ↓
第四步:学习框架(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事件、异步编 程)

        这三篇文章涵盖了一个前端工程师需要掌握的基础知识体系。

        但学习永无止境。

        前端技术发展很快,新的框架、新的工具、新的技术不断涌现。你需要持续学习,跟上技术发展的步伐。

        记住几个核心原则:

1. 打好基础:基础不牢,地动山摇

2. 多动手实践:看懂了不代表学会了

3. 持续学习:技术更新很快,不能停下脚步

4. 培养编程思维:编程不仅仅是写代码,更是解决问题

        最后的最后

        前端开发是一门很有趣的技术。你可以用代码创造出漂亮的网页,实现各种交互效果,给用户带来良好的体验。

        希望这三篇文章能帮你打下坚实的基础,开启你的前端开发之旅。

        如果你在学习过程中遇到问题,欢迎在评论区留言。我会尽力解答。

祝你在前端开发的道路上越走越远!

附录:完整知识体系图

前端开发知识体系
│
├─ 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)

        版权声明

                本文为原创文章,转载请注明出处。未经作者许可,禁止用于商业用途。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐