recursal/MDN huggingface dataset:
JavaScript 第一步
==============

在第一个 JavaScript 板块，带领各位体验编写 JavaScript 程序前，首先回答一些基本问题：「什么是 JavaScript？」，「它看上去是什么样的？」，「它能做什么？」。此后，我们将详细讨论一些关键构件，例如变量、字符串、数值和数组。

事前准备
----

学习这个板块前，你不需要预先了解任何 JavaScript 知识，但你应当对 HTML 和 CSS 有所熟悉。我们建议学习 JavaScript 前，先完成以下板块阅读：

* 开始使用 Web（包括 JavaScript 基础简介）。
* HTML 简介。
* CSS 简介。

**备注：** 如果你无法在你使用的电脑/平板/其他设备上创建自己的文件，尝试使用在线编程应用来运行（大部分）代码示例，例如 JSBin 和 Glitch。

学习指南
----

什么是 JavaScript？

欢迎来到 MDN JavaScript 新手课程！第一篇文章，我们将从较高层次审视 JavaScript，解答诸如「它是什么？」、「它在做些什么？」的问题，确保你理解 JavaScript 的用途。

JavaScript 初体验

你已经学习了一些 JavaScript 理论，了解了可以用它做什么，接下来我们将通过一个非常实用的教程，带给你一节 JavaScript 基本特性速成课。在这里你将一步一步构建出一个「猜数字」游戏。

哪里出错了？JavaScript 疑难解答

构建上篇文章中的「猜数字」游戏时，你可能发现它没法运行。不要害怕——这篇文章来解救正为问题挠头的你，它为你提供一些从 JavaScript 程序中发现并解决问题的思路。

存储你需要的信息——变量

读过最近几篇文章，你应当了解 JavaScript 是什么，它能为你做什么，如何搭配其他 web 技术使用，以及从较高层次来看，它的主要特性是什么样的。这篇文章，我们将深入真正的基础，看看如何使用 JavaScript 的基本构件——变量。

JavaScript 中的基本运算——数值和运算符

这一课我们讨论 JavaScript 的运算——如何将运算符与其他特性结合使用，完美操作数值来实现需求。

文字处理——JavaScript 字符串

接下来将目光转向字符串——编程世界中文字片段被称为字符串。本文涉及你在学习 JavaScript 时应当了解的有关字符串的所有常见情形，例如生成字符串、字符串中的引用以及合并字符串。

实用字符串方法

我们已经了解字符串的基本内容，接下来再上一个台阶，思考利用字符串内建方法实现的实用操作，例如获取字符串长度、字符串合并与分割、替换字符串中特定字符，等等。

数组

这个版块最后一篇文章，我们来看数组——干净整洁地把一连串数据项存储在同一个变量名下。这里我们要理解为什么说它实用，探索如何创建数组，如何获取、添加、删除数组中的项目等等内容。

自我评估
----

下面的评估会检验你对上述学习指南中 JavaScript 基础的理解。

笑话生成器

这项评估中，你将运用你在这个版块的文章中学到的知识，构建一个生成随机笑话的好玩 app。玩得开心！
客户端 Web API
===========

当你给网页或者网页应用编写客户端的 JavaScript 时，你很快会遇上应用程序接口（API）——这些编程特性可用来操控网站所基于的浏览器与操作系统的不同方面，或是操控由其他网站或服务端传来的数据。在这个单元里，我们将一同探索什么是 API，以及如何使用一些在你开发中将经常遇见的 API。

预备知识
----

若想深入理解这个单元的内容，你必须能够以自己的能力较好地学完之前的几个章节 (JavaScript 第一步, JavaScript基础要件, 和JavaScript对象介绍). 这几部分涉及到了许多简单的 API 的使用，如果没有它们我们将很难做一些实际的事情。在这个教程中，我们会认为你懂得 JavaScript 的核心知识，而且我们将更深入地探索常见的网页 API。

若你知道 HTML 和 CSS 的基本知识，也会对理解这个单元的内容大有裨益。

**备注：** 如果你正在使用一台无法创建你自身文件的电脑、平板或其他设备，你可以尝试使用一些在线网页编辑器如JSBin或者Glitch，来尝试编辑一些代码示例。

向导
--

Web API 简介

首先，我们将从一个更高的角度来看这些 API —它们是什么，它们怎么起作用的，你该怎么在自己的代码中使用它们以及他们是怎么构成的？我们依旧会再来看一看这些 API 有哪些主要的种类和他们会有哪些用处。

操作文档

当你在制作 WEB 页面和 APP 时，一个你最经常想要做的事就是通过一些方法来操作 WEB 文档。这其中最常见的方法就是使用文档对象模型 Document Object Model (DOM)，它是一系列大量使用了 `Document` object 的 API 来控制 HTML 和样式信息。通过这篇文章，我们来看看使用 DOM 方面的一些细节，以及其他一些有趣的 API 能够通过一些有趣的方式改变你的环境。

从服务器获取数据

在现代网页及其 APP 中另外一个很常见的任务就是与服务器进行数据交互时不再刷新整个页面，这看起来微不足道，但却对一个网页的展现和交互上起到了很大的作用，在这篇文章里，我们将阐述这个概念，然后来了解实现这个功能的技术，例如 `XMLHttpRequest` 和 Fetch API.（抓取 API）。

第三方 API

到目前为止我们所涉及的 API 都是浏览器内置的，但并不代表所有。许多大网站如 Google Maps, Twitter, Facebook, PayPal 等，都提供他们的 API 给开发者们去使用他们的数据（比如在你的博客里展示你分享的推特内容）或者服务（如在你的网页里展示定制的谷歌地图或接入 Facebook 登录功能）。这篇文章介绍了浏览器 API 和第三方 API 的差别以及一些最新的典型应用。

绘制图形

浏览器包含多种强大的图形编程工具，从可缩放矢量图形语言 Scalable Vector Graphics (SVG) language，到 HTML 绘制元素 `<canvas>` 元素 (The Canvas API and WebGL). 这篇文章提供了部分 canvas 的简介，以及让你更深入学习的资源。

视频和音频 API

HTML5 能够通过元素标签嵌入富媒体——`<video>` and `<audio>`——而将有自己的 API 来控制回放，搜索等功能。本文向你展示了如何创建自定义播放控制等常见的任务。

客户端存储

现代 web 浏览器拥有很多不同的技术，能够让你存储与网站相关的数据，并在需要时调用它们，能够让你长期保存数据、保存离线网站及其他实现其他功能。本文解释了这些功能的基本原理。
异步 JavaScript
=============

在这个模块，我们将查看异步 JavaScript，异步为什么很重要，以及怎样使用异步来有效处理潜在的阻塞操作，比如从服务器上获取资源。

#### 想成为一名前端工程师？

我们汇总了一门课程，其中包含你实现目标所需要的所有基本信息。

**点击开始**

预备知识
----

异步 JavaScript 是一个相当高级的话题，建议你先完成 JavaScript 第一步和创建 JavaScript 代码块 两个模块的学习后再来学习。

**备注：** 如果你工作在一个无权创建自己文件的电脑/平板/其他设备上，你需要在一个在线编程工具上试验（大多数）代码示例，如 JSBin 或者 Glitch.

指南
--

异步 JavaScript 简介

在这篇文章中我们将介绍 **同步编程** 和 **异步编程** 是什么，为什么我们总是需要异步编程技术，异步函数过去是怎样在 JavaScript 上实现的，以及这些方式的问题有哪些。

如何使用 Promise

我们将在这里介绍 Promise 并向你展示如何使用基于 Promise 的 API。我们也会介绍 `async` 和 `await` 关键字。

应用一个基于 Promise 的 API

本文概述了如何实现一个我们自己的基于 Promise 的 API。

Worker 简介

Worker 使你能够在独立的线程中运行任务来保持你的主要代码的可响应性。在这篇文章中我们将把一个长时间运行的同步函数重写为使用 Worker 的示例。

测验
--

序列动画

这个测验要求你使用 Promise 来播放一组特定序列的动画。

参见
--

* 由 Marijn Haverbeke 编写的电子书籍 Eloquent JavaScript 中的 异步编程。
解决 JavaSctript 代码的常见问题
======================

以下链接指向撰写 JavaScript 代码时可能遇见的问题。

初学者常见的错误
--------

### 正确的拼写和使用

如果你的代码不工作或浏览器抱怨某些东西是未定义的，请检查你是否正确拼写了所有的变量名称，函数名称等。

导致问题的一些常见的内置浏览器函数有：

| 正确 | 错误 |
| --- | --- |
| `getElementsByTagName()` | `getElementbyTagName()` |
| `getElementsByName()` | `getElementByName()` |
| `getElementsByClassName()` | `getElementByClassName()` |
| `getElementById()` | `getElementsById()` |

### 分号的位置

必须确保没有错误地放置分号，例如：

| 正确 | 错误 |
| --- | --- |
| `elem.style.color = 'red';` | `elem.style.color = 'red;'` |

### 函数

函数有很多容易出错的地方。

最常见的错误之一是函数被声明了却没有被调用。例如：


```js
function myFunction() {
  alert("This is my function.");
}
```


这个函数不会执行，除非你调用它，例如：


```js
myFunction();
```


#### 函数作用域

记住，函数拥有自己的作用域——你不能从函数外部访问一个函数内的变量值，除非你在全局声明了该变量（即不在任何函数内），或者从函数外部获得它的返回值。

#### 在 return 语句之后运行代码

还要记住，当你向一个函数外部返回一个值时，JavaScript 解释器会退出这个函数——在 return 语句之后，不会执行任何代码。

事实上，如果你在返回语句之后有代码，某些浏览器（如 Firefox）会在开发人员控制台中显示出一条错误消息。Firefox 在返回语句后会给你“无法运行到的代码”的提示。

### 对象标记法与正常赋值

当你在 JavaScript 中正常赋值时，使用等号：


```js
const myNumber = 0;
```


但是在对象中，需要小心地使用正确的语法标签。你需要使用花括号来包裹一个对象，冒号来分隔成员名称和值，并用逗号来分隔每个成员，例如：


```js
const myObject = {
  name: "Chris",
  age: 38,
};
```

基本定义
----

* JavaScript 是什么？
* 变量是什么？
* 字符串是什么？
* 数组是什么？
* 循环是什么？
* 函数是什么？
* 事件是什么？
* 对象是什么？
* JSON 是什么？
* web API 是什么？
* DOM 是什么？
基本用例
----

### 常见

* 怎么在页面中添加 JavaScript?
* 怎么在 JavaScript 中添加注释？
### 变量

* 如何声明变量？
* 如何初始化变量的值？
* 如何更新变量的值？（参见 赋值运算符）
* JavaScript 中有哪些数据类型？
* '弱类型'是什么意思？
### 数学

* 在 web 开发中需要处理什么样的数字值？
* JavaScript 如何处理基本的数学运算？
* 什么是运算符的优先级，如何在 JavaScript 中处理优先级问题？
* 如何在 JavaScript 中增加或减少值？
* 如何在 JavaScript 中比较值的大小？（例如，查看哪个值更大，或检查一个值是否与另外一个值相等）
### 字符串

* 如何在 JavaScript 中创建字符串？
* 我需要使用单引号，还是双引号？
* 我如何转义字符串中的字符？
* 我如何将字符串拼接在一起？
* 可以将字符串和数字拼接在一起吗？
* 如何得到字符串的长度？
* 如何得到字符串某个特定位置的字符？
* 如何从给定字符串中找到并提取特定子字符串？
* 如何改变字符串的大小写？
* 如何将特定子字符串替换为另外一个？
### 数组

* 怎么创建数组？
* 如何访问和修改数组中的元素？（包括多维数组）
* 怎么获取数组的长度？
* 怎么添加和移除数组中的元素？
* 如何将一个字符串拆分为数组，或将数组拼接成一个字符串？
### JavaScript 调试

* 什么是错误的基本类型？
* 什么是浏览器开发工具，如何使用它？
* 怎么在 JavaScript 控制台打印值？
* 怎么使用断点和其他 JavaScript 调试工具？

有关 JavaScript 调试的更多内容，请查阅处理 JavaScript 常见问题页面，也可以查看其他常见错误的描述。

### 在代码中作出判断

* 如何根据变量的值或其他条件执行不同代码块？
* 如何使用 if ...else 语句？
* 如何将决策的代码块嵌套在其他代码块之中？
* 如何在 JavaScript 中使用与、或、非运算符？
* 如何方便地处理单一条件产生的多重选择？
* 如何使用三元运算符快速作出基于真假的二重选择？
### 循环/迭代

* 如何重复运行相同的代码？
* 如何在满足某些条件下退出循环？
* 如何在满足某些条件下跳转至下一次循环迭代？
* 如何使用 while 和 do ... while 循环？
中级用例
----

### 函数

* 如何找到浏览器中的内置函数？
* 函数和方法有什么不同？
* 如何创建自己的函数？
* 如何运行（或调用）函数？
* 什么是匿名函数？
* 如何在调用函数时指定参数？
* 什么是函数作用域？
* 什么是函数返回值，如何使用它们？
### 对象

* 如何创建对象？
* 什么是点表示法？
* 什么是括号表示法？
* 如何获取和设置对象的方法和属性？
* 对象中的 `this` 是什么？
* 什么是面向对象编程？
* 什么是构造器和实例，如何创建它们？
* 在 JavaScript 中创建对象的方法都有哪些？
### JSON

* 如何构建 JSON 数据，并使用 JavaScript 读取它？
* 如何将 JSON 文件加载至页面上？
* 如何将 JSON 对象转换为字符串，或者再转换回来？
### 事件

* 什么是事件处理器，怎样使用它们？
* 什么是内联事件处理器？
* `addEventListener()` 函数的作用，如何使用它？
* 我该使用什么样的机制将事件代码添加到我的网页上？
* 什么是事件对象，如何使用它？
* 如何防止默认事件行为？
* 事件如何在嵌套元素中触发？（事件传递及其相关内容——事件冒泡及捕获）
* 什么是事件委托，它如何工作？
### 面向对象的 JavaScript

* 什么是对象原型？
* 什么是构造器属性，如何使用它？
* 如何向构造器中添加方法？
* 如何创建一个新的构造函数，从父构造函数中继承其成员？
* 什么时候应当在 JavaScript 中使用继承？
### Web API

* 如何使用 JavaScript 操作 DOM 模型（如添加或删除元素）？
创建 JavaScript 代码块
=================

在这个模块中，我们将继续介绍 JavaScript 的关键基本特性，在这一章中我们将关注条件控制语句、循环语句、函数模块、事件等通用代码块。你可能在之前的的课程中见过这些模块，但仅仅是见过—在这篇模块中我们将明确讨论这些模块。

预备知识
----

在开始这部分模块之前，你应该熟悉基本的 HTML 和 CSS, 并且已经看完我们之前的模块：JavaScript 第一步。

**备注：** 如果你在使用无法创建自己文件的电脑/平板/其他设备，你可以试试在线编辑器，例如 JSBin 或 Glitch.

指南
--

在代码中做决定 — 条件

在任何程序语言中，程序需要根据不同的输入数据作出相应的选择并执行相关的操作。例如，在游戏中，如果玩家的生命值是 0，那么游戏就结束了。在天气应用中，如果在早上打开应用，则显示一个太阳升起的图片，如果在晚上打开，则显示星星和月亮。在这篇文章里我们将探索如何在 JS 中使用条件结构。

循环语句

有时候你需要在一个行中重复执行某一个任务。例如，查看一整列的名字。在程序中，循环能非常好的处理好这个问题。在本章中我们将介绍 JavaScript 的循环语句。

函数 — 可重用的代码块

在编码中的另一个基本概念是函数 (functions)。 **函数** 允许你在定义的区块内存储一段代码用来执行一个单独的任务，然后调用该段代码时，你需要使用一个简短的命令，而不用重复编写多次该段代码。在这篇文章中我们将探讨函数的基本概念，如语法、如何调用定义的函数、作用域和参数。

打造自己的函数

本文结合前几篇文章中所涉及的基本理论，提供了一个实践经验。在这里你会得到一些实践，并且编写自己的自定义函数。随后，我们也将进一步解释一些与函数相关的有用的细节。

函数返回值

在这个课程中，我们要讨论的最后一个基本概念是返回值（通过返回值结束我们的函数）。有些函数在完成后不返回任何值，而有些函数返回。重要的是了解返回的值是什么，和如何在你的代码中使用他们，以及如何使自定义的函数返回需要的值。

事件介绍

事件是你正在编写的系统中发生的动作或事件，系统告诉你的是这些动作或事件，如果需要的话，你可以以某种方式对它们做出反应。例如，如果用户单击网页上的按钮，你可能希望通过显示信息框来响应该操作。在这最后一篇文章中，我们将重点讨论一些围绕事件有关的概念，看看他们如何在浏览器中工作。

评估
--

下面的评估将测试你对 JavaScript 基础知识的理解。

图片画廊

现在我们已经学习了构建 JavaScript 的基本代码块，我们会通过构建一个在很多网站上相当常见的项目——一个由 JavaScript 驱动的相册，来测试你循环、函数、条件语句和事件方面的知识。
JavaScript 对象入门
===============

在 JavaScript 中，大多数事物都是对象，从作为核心功能的字符串和数组，到建立在 JavaScript 之上的浏览器 API 。你甚至可以自己创建对象，将相关的函数和变量高效地封装打包成便捷的数据容器。对于进一步学习 JavaScript 语言知识而言，理解这种面向对象（object-oriented, OO）的特性是必不可少的，所以，我们提供了这个模块来帮助你了解这一切。这里我们会先详细介绍对象的理论和语法，再介绍如何创建对象。

预备知识
----

开始这个模块之前，你应当已经对 HTML 和 CSS 有所了解。我们建议你通读 HTML 入门和 CSS 入门模块，再开始了解 JavaScript。

详细了解 JavaScript 对象之前，你应当已经对 JavaScript 基础有所熟悉。尝试这个模块之前，请通读 JavaScript 第一步 和 JavaScript 基础要件

**备注：** 如果你无法在当前使用的电脑/平板/其他设备上创建自己的文件，可以使用在线编程网站如 JSBin 或 Glitch，来试验文章中的（大多数）代码。

指南
--

对象基础

在了解 JavaScript 对象的第一篇文章中，我们将介绍 JavaScript 对象的语法，并回顾先前课程中讲过的某些 JavaScript 功能。你会发现，你已经在使用的很多功能本质上都是对象。

适合初学者的面向对象 JavaScript

了解基础后，我们将关注面向对象 JavaScript (OOJS)。本文将介绍面向对象编程 (OOP) 的基本理论，然后讲解 JavaScript 如何通过构造器 (constructor) 函数模拟对象类别 (class)、如何创建对象实例 (instance)。

对象原型

通过原型 (prototype) 这种机制，JavaScript 中的对象从其他对象继承功能特性；这种继承机制与经典的面向对象编程语言不同。本文将探讨这些差别，解释原型链如何工作，并了解如何通过 `prototype` 属性向已有的构造器添加方法。

JavaScript 中的继承

了解了 OOJS 的大多数细节之后，本文将介绍如何创建“子”对象类别（构造器）并从“父”类别中继承功能。此外，我们还会针对何时何处使用 OOJS 给出建议。

使用 JSON 数据

JavaScript Object Notation (JSON) 是一种将结构化数据表达为 JavaScript 对象的标准格式，其常用于在网站上表达或传输数据（比如：从服务器向客户端发送数据，使之显示在网页上）。你会经常遇到它，因此本文将告诉你如何在 JavaScript 中使用 JSON 数据，包括访问 JSON 对象中的数据条目、编写自己的 JSON 数据等等。

构建对象实战

在前面的文章中我们了解了 JavaScript 对象基本理论和语法，为你打下坚实的基础。本文中你需要进行实战练习，通过构建自定义 JavaScript 对象的实践过程，编写一个有趣而又多彩的程序——“彩色弹跳球”。

学习评估
----

向“弹跳球”演示程序添加新功能

在这个评估中，你需要以上一篇文章中的“弹跳球”演示为起点，向这个演示程序新增一些有趣的功能。
技能测试：面向对象的 Javascript
=====================

这个测试的目的是为了评估你是否已经理解了我们的 JavaScript 中的类这一文章。

**备注：** 你可以尝试在下方的交互式编辑器，但是若你下载源码并使用在线工具（例如 CodePen、jsFiddle 或 Glitch）来尝试这些任务，可能会更有帮助。

如果你遇到了困难，请联系我们以寻求帮助——见本页面底部的评估或进一步帮助。

**备注：** 在下方的示例中，如果你的代码中存在错误内容，这些错误将在页面的结果面板中显示，以此来帮助你想出解决方案（若是下载的版本，请进入浏览器的 JavaScript 控制台）。

面向对象的 Javascript 1
------------------

在这个任务中，我们为你提供了 `Shape` 类的初始定义。它有三个属性：`name`、`sides` 和 `sideLength`。这个类只模拟了所有边长都相同的形状，例如：正方形或等边三角形。

我们希望你：

* 向这个类添加构造函数。构造函数接受 `name`、`sides` 和 `sideLength` 属性的参数，并对它们进行初始化。
* 向这个类添加一个新的 `calcPerimeter()` 方法，用于计算它的周长（形状外边缘的长度），并将结果记录到控制台中。
* 创建 `Shape` 类的一个新的实例，名为 `square`。将其 `name` 属性值设为 `square`，`sides` 属性值设为 `4`，`sideLength` 属性值设为 `5`。
* 调用 `calcPerimeter()` 方法，以查看它是否按预期将计算结果记录到浏览器的控制台中。
* 创建 `Shape` 类的一个新的实例，名为 `triangle`。将其 `name` 属性值设为 `triangle`，`sides` 属性值设为 `3`，`sideLength` 属性值设为 `3`。
* 调用 `triangle.calcPerimeter()`，以查看它是否正常工作。

尝试更新下面的实时代码，以重现完成的示例：

下载此任务的初始代码，以便在你自己的编辑器或在线编辑器中尝试。

面向对象的 Javascript 2
------------------

接下来，我们希望你创建一个继承自 `Shape` 的 `Square` 类，并添加一个 `calcArea()` 方法，用于计算正方形的面积。同时，设置构造函数，以便 `Square` 对象实例的 `name` 属性自动设置为 `square`，`sides` 属性自动设置为 `4`。因此，在调用构造函数时，你只需要提供 `sideLength` 属性。

创建一个使用适当属性值的 `Square` 类的实例，名为 `square`，并调用它的 `calcPerimeter()` 和 `calcArea()` 方法，以表明其是否正常工作。

尝试更新下面的实时代码，以重现完成的示例：

下载此任务的初始代码，以便在你自己的编辑器或在线编辑器中尝试。

评估或进一步帮助
--------

你可以在上面的交互式编辑器中练习这些示例。

如果你希望对自己的工作成果进行打分评估，或者遇到了困难并希望寻求帮助：

1. 将你完成的内容放到在线、可分享的编辑器，如：CodePen、jsFiddle 或 Glitch。你可以自行编写代码，或使用上面小节中链接的初始文件。
2. 在 MDN Discourse forum Learning category 中发贴寻求打分评估或帮助。你的贴子需要包含：
    * 一个描述的标题，如：“Assessment wanted for OOJS 1 skill test”。
    * 你已经尝试过的详细内容，以及你希望我们能够做什么，例如：你遇到了困难，想要寻求帮助；或希望得到打分评估。
    * 一个指向用于打分评估或寻求帮助的示例代码的链接（使用上文中提到的任意一种在线的、可分享的编辑器）。这是一种很好的形式——如果别人没法看到你的代码，他们很难对你提供代码上的帮助。
    * 一个指向实际任务或评估页面的链接，以便我们找到你需要得到帮助的问题。
序列动画
====

* 上一页
* Overview: Asynchronous

在本测验中，你将使用我们在如何使用 Promise 中学习的一些技术来更新页面，使它能够按顺序播放一系列动画。

|  |  |
| --- | --- |
| 前置条件： | 基本的计算机知识，对 JavaScript 基础知识的一定了解，能够使用基于 Promise 的 API。 |
| 目标： | 测试使用基于 Promise 的 API 的能力。 |

起点
--

创建一份 https://github.com/mdn/learning-area/tree/main/javascript/asynchronous/sequencing-animations/start 的本地副本。它包含下列文件：

* alice.svg
* index.html
* main.js
* style.css

你需要编辑的唯一一个文件是“main.js”。

如果你在浏览器中打开“index.html”，你会看到三张图片呈对角排列：

![序列动画测验页面的屏幕截图](/zh-CN/docs/Learn/JavaScript/Asynchronous/Sequencing_animations/sequencing-animations.png)

这些图像取自我们的 Using the Web Animations API 指南。

项目简介
----

我们希望更新此页面，来将动画依次应用于所有三个图像。也就是说，当第一个动画完成时，我们开始第二个动画，当第二个完成时，我们开始第三个动画。

要应用的动画已经在“main.js”中被定义：效果是旋转图像并缩小它至消失。

请查看完成的示例来更好地了解页面的预期工作方式。注意：动画只会执行一次，你需要重新加载页面来重新运行它们。

完成步骤
----

### 设置第一个图像的动画

我们使用 Web Animations API 对图像进行动画处理，特别是 `element.animate()` 方法。

更新“main.js”以添加对 `alice1.animate()` 的调用，就像这样：


```js
const aliceTumbling = [
  { transform: "rotate(0) scale(1)" },
  { transform: "rotate(360deg) scale(0)" },
];

const aliceTiming = {
  duration: 2000,
  iterations: 1,
  fill: "forwards",
};

const alice1 = document.querySelector("#alice1");
const alice2 = document.querySelector("#alice2");
const alice3 = document.querySelector("#alice3");

alice1.animate(aliceTumbling, aliceTiming);
```


重载页面，你应该就会看到第一个图像旋转收缩的动画。

### 设置所有图像的动画

接下来，我们希望在 `alice1` 完成时启动 `alice2` 的动画，在 `alice2` 完成时启动 `alice3` 的动画。

`animate()` 方法返回 `Animation` 对象。这个对象有一个 `finished` 属性，这是会在一个在动画播放结束时兑现（fulfilled）的 `Promise`。所以我们可以利用这个 Promise 获得开始下一个动画的时机。

我们希望你尝试一些不同的方式来实现这个功能，以便于加强对使用 Promise 的不同方式的理解。

1. 首先，实现一个能够工作的代码，但它存在“回调地狱”问题（我们在关于回调的讨论中提到过）的 Promise 版本。
2. 接下来，使用 Promise 链来实现它。注意：可以用箭头函数的不同形式来编写这个函数。尝试这些不同的形式。哪个最简洁？哪个可读性最好？
3. 使用 `async` 和 `await` 来实现它。

别忘了，`element.animate()` 并不返回一个 `Promise`：它返回一个 `Animation` 对象，该对象具有一个 `finished` 属性，这个属性才是 `Promise`。

评估或进一步的帮助
---------

如果你希望自己的作品被评估，或者遇到困难想寻求帮助：

1. 将作品放入在线共享编辑器中，如 CodePen，jsFiddle，或者 Glitch。
2. 在 MDN 论坛学习分类中写一篇文章寻求评估和/或帮助。你的文章应该包括：
    * 一个描述性的标题，如“请帮助评估测序动画”。
    * 详细说明你已经尝试过的方法，以及你希望我们做的事情，例如：你遇到困难需要帮助，或者你完成了作品，需要评估。
    * 一个指向你的作品的链接（托管在在线共享编辑器中，如步骤 1 所述），这是一个很好的实践ーー如果你看不到他们的代码，就很难帮助有编码问题的人。
    * 指向实际任务或评估页面的链接，这样我们就可以找到你需要帮助的问题。
* 上一页
* Overview: Asynchronous
图片库
===

* 上一页
* Overview: Building blocks

我们已经学习了 JavaScript 基础的块结构，下面我们通过编写一个常见的基于 JavaScript 的图片库来测验一下你对于循环、函数、条件和事件的掌握情况。

|  |  |
| --- | --- |
| 前提： | 请读完本章其他所有小节的内容后再开始这个测验。 |
| 目标： | 测试你对 JavaScript 的循环、函数、条件语句和事件处理的掌握程度。 |

起点
--

下载压缩包并在本地解压。

另外，你还可以使用类似 JSBin 或 Glitch）这些在线编辑器来完成测验。你可以将 HTML、CSS 和 JavaScript 粘贴到这几个在线编辑器中。如果你使用的在线编辑器没有单独的 JavaScript/CSS 面板，请将它们放入 HTML 页面内联的 `<script>`/`<style>` 元素中。

**备注：** 如果你遇到了困难，请联系我们以寻求帮助——见本页面底部的评估或进一步帮助。

项目简介
----

我们提供了一些 HTML、CSS、照片和几行 JavaScript 代码。需要你来编写必要的 JavaScript 代码让这个项目运行起来。HTML 的 body 部分如下：


```html
<h1>Image gallery example</h1>

<div class="full-img">
  <img class="displayed-img" src="images/pic1.jpg" />
  <div class="overlay"></div>
  <button class="dark">Darken</button>
</div>

<div class="thumb-bar"></div>
```


该示例如下所示：

![](/zh-CN/docs/Learn/JavaScript/Building_blocks/Image_gallery/gallery.png)

以下是本例中 CSS 文件最值得关注的部分：

* `full-img <div>` 中有三个绝对定位的元素：一个显示全尺寸图片的 `<img>`，一个空 `<div>`（覆盖于 `<img>` 之上，且与之大小相同，用来设置半透明背景色来使图片变暗），和一个用来控制变暗效果的 `<button>`。
* 将 `thumb-bar <div>` 中图片（即“缩略图”）的宽度设置为 20%，并且将它们沿左侧浮动，使得它们在同一行上依次排列。

JavaScript 部分则需要实现：

* 声明一个 `const` 数组，用于列出每张图像的文件名，例如 `'pic1.jpg'`。
* 迭代数组中的文件名，为每一个文件名创建一个 `<img>` 元素，并将其插入到 `thumb-bar <div>` 中，这样图片就会嵌入页面。
* 为 `thumb-bar <div>` 里的每个 `<img>` 元素添加一个 click 事件监听器，在图片被点击时相应的图片将被显示到 `displayed-img <img>` 元素上。
* 给 `<button>` 元素添加一个 click 事件监听器，当按钮被点击时，将全尺寸图片变暗，再次点击时取消。

可以看一下完成的示例，体会一下。（别偷看代码哦）

详细步骤
----

以下是你的工作。

声明图像文件名数组
---------

你需要创建一个用于列出所有需要包含在图片库中的图像的文件名。这个数组应该以常量的形式声明。

### 迭代照片

我们提供的代码中用一个名为 `thumbBar` 的变量用来存储 `thumb-bar <div>` 的引用，创建了一个新的 `<img>` 元素，将它的 `src` 属性值设置成 `xxx` 占位符，并且将这个新的 `<img>` 元素添加到 `thumbBar` 中。

你需要：

1. 将“Looping through images”注释下方的代码放到一个循环之中，这个循环会迭代数组中所有的文件名。
2. 对于每一次循环迭代，将占位符 `xxx` 替换为代表图像路径的字符串。我们需要设置每一个图像的 `src` 属性。请注意，每一张图像都在 `images` 文件夹内，文件名为 `pic1.jpg`、`pic2.jpg`，等等。
### 为每一个缩略图添加 click 事件监听器

每次迭代中，你需要给当前的 `newImage` 加上一个 click 事件监听器——它应该查询当前图像的 `scr` 属性值，然后将获取的 `src` 属性值设置为 `displayed-img <img>` 元素 `src` 属性的值。

或者，你可以只为缩略图栏（`thumb-bar <div>`）添加事件监听器。

### 为变亮/变暗按钮编写处理器

最后还剩变亮/变暗的 `<button>`。我们已经提供了一个名为 `btn` 的变量来存储 `<button>` 的引用。需要添加一个 click 事件监听器：

1. 检查当前 `<button>` 按钮的类名称，你可以使用 `getAttribute()` 方法获得。
2. 如果类名是 `"dark"`，则将 `<button>` 的类名变为 `"light"`（使用 `setAttribute()`），文本内容变为“Lighten”，然后将蒙板 `<div>` 的 `background-color` 设为 `"rgba(0,0,0,0.5)"`。
3. 如果类名不是 `"dark"`，则将 `<button>` 的类名变为 `"dark"`，文本内容变为 "Darken"，然后将蒙板 `<div>` 的 `background-color` 设为 `"rgba(0,0,0,0)"`。

以下是实现上述 2、3 点所提功能的基本代码：


```js
btn.setAttribute("class", xxx);
btn.textContent = xxx;
overlay.style.backgroundColor = xxx;
```

提示
--

* 完全不需要修改 HTML 和 CSS 文件。
评估或进一步帮助
--------

如果你希望对自己的工作成果进行打分评估，或者遇到了困难并希望寻求帮助：

1. 将你完成的内容放到在线、可分享的编辑器，如：CodePen、jsFiddle 或 Glitch。
2. 在 MDN Discourse forum Learning category 中发贴寻求打分评估或帮助。你的贴子需要包含：
    * 一个描述的标题，如：“Assessment wanted for Image gallery”。
    * 你尝试的详细过程，以及你希望我们能够做什么，例如：你遇到了困难，想要寻求帮助；或希望得到打分评估。
    * 一个指向用于打分评估或寻求帮助的示例代码的链接（使用上文中提到的任意一种在线的、可分享的编辑器）。这是一种很好的形式——如果别人没法看到你的代码，他们很难对你提供代码上的帮助。
    * 一个指向实际任务或评估页面的链接，以便我们找到你需要得到帮助的问题。
* 上一页
* Overview: Building blocks
解决常见的 CSS 问题
============


 以下链接提供了一些你在使用 CSS 时可能遇到的常见问题的解决方案。
主要使用事项
------

### 基础

* 如何应用 CSS 到 DOM 中？
* CSS 如何留白？
* CSS 如何添加注释？
* CSS 如何通过元素名、类名以及 ID 筛选元素？
* CSS 如何通过属性名和属性内容筛选元素？
* 如何使用伪类？
* 如何使用伪元素？
* 如何将多个选择器应用于同一个规则？
* 如何在 CSS 中指定颜色？
* 如何在浏览器中调试 CSS？
### 样式和内容

* 如何给文字添加样式？
* 如何定制元素列表？
* 如何给链接添加样式？
* 如何给文本添加阴影？
### 盒子和布局

* 如何调整 CSS 盒模型大小？
* 如何控制盒模型溢出？
* 如何控制 CSS 盒模型中背景绘制部分？
* 如何理解 inline、block 以及 inline-block？
* How to create fancy boxes (en-US) (请一并查看 Styling boxes 模块)
* 如何使用 background-clip 控制背景图覆盖？
* 如何使用 box-sizing 完全改变盒模型？
* 如何改变背景色？
* 如何修改边框？
* 如何给 HTML 表格添样式？
* 如何添加盒子阴影？
罕见问题与进阶技巧
---------

CSS 允许一些高级的设计技巧。这些文章可以帮助你解决一些更复杂的使用案例。

### 通用

* 如何计算 CSS 选择器的优先级？
* 如何控制 CSS 中的继承？
### 进阶效果

* 如何使用 CSS 滤镜？
* 如何在 CSS 中使用混合模式？
### 布局

* 使用 CSS flex 布局
* 使用 CSS 多列布局
* 使用 CSS 生成内容
为文本添加样式（样式化文本）
==============

掌握了 CSS 语言的基础之后，对于你来说，下一个需要关心的 CSS 主题就是为文本添加样式——一个你将会最经常使用 CSS 做的事情。在这里，我们专注于为文本样式的基础，包括设置字体、粗细、斜体、行还有字符间距、阴影以及文本的其他特征。我们将会通过在你的网页中应用自定义字体、样式化列表以及链接来圆满地结束本模块。

前提
--

在开始这一模块之前，你应当像 HTML 介绍 模块中所探讨的，已经熟悉了基本的 HTML，以及像 CSS 介绍 中所详述的，对自己的 CSS 基础感觉还满意。

**备注：** 如果你所使用的是不能创建自己的文件的电脑、平板电脑或其他设备的话，你可以在一个在线编码程序 JSBin 或 Glitch 中尝试（大部分的）代码例子。

导引
--

这个模块包括了以下文章，这些文章将教会你所有的基本功以支持你为 HTML 文本内容添加样式。

基本的文本以及字体样式

在本文章中，我们将通篇了解文本、字体样式的所有基础，包括设置字体粗细（font weight）、字体系列及样式（family and style）、字体缩写（font shorthand）、文本排列（text alignment）和其他的效果，还有行（line）以及字符间距（letter spacing）。

样式化列表

对于大部分内容来说，列表的行为表现跟其他任何文本其实差不多，但你也需要了解还有一些专门用于列表的 CSS 样式以及考虑一些最好的实践方式。本文章将阐释这一切。

样式化链接

当你为链接添加样式时，很重要的一点是要去理解怎样有效地使用伪类去修饰链接的状态，以及怎么去修饰不同的接口功能例如导航菜单和面板中所使用的链接。我们将会在这篇文章中讨论这些话题。

网络字体

在这里我们将会详细地探索网络字体——这会允许你与你的网页一同下载自定义字体，来实现更为不同的个性化字体样式。

评估
--

以下的评估将会评测你对以上导引所涵盖的为文本添加样式的技术的理解。

对一个社区学校的主页进行排版

在这个评估中，我们通过让你为一个社区学校的主页添加文本样式来测试你对文本样式的理解程度。
CSS 构建
======

这个模块承接学习 CSS 第一步——即你对 (CSS) 语言和其语法已经足够熟悉、并且有了一些基本的使用经验，该是稍微深入点学习的时候了。这个模块着眼于级联和继承，所有可供使用的选择器类型，单位，尺寸，背景、边框样式，调试，等等等等。

本文目标是，在你进一步了解为文本添加样式和 CSS 布局之前，为你提供一个助你写出合格 CSS 和理解所有基本理论的工具箱。

先决条件
----

在开始本模块之前，你应该已经掌握：

1. 使用计算机的基本知识，能够被动使用网络（也就是查看网页的内容）。
2. 建立基本工作环境（详见安装基础软件），知道如何建立和管理文档（详见处理文件）。
3. HTML 基础知识（参见 HTML 介绍模块）。
4. CSS 基础知识（参见学习 CSS 第一步模块）。

**备注：** 如果你此刻正使用一台电脑/笔记本/其他设备，而你无法创建自己的文件，那你可以在诸如 JSBin 或 Glitch 等网络编辑程序上尝试（多数）程序案例。

指南
--

本模块包含以下文章，这些文章覆盖了绝大部分 CSS 语言基础。在学习这些文章的过程中，会有很多练习题供你检验自己的理解程度。

层叠与继承

本节目标是帮你建立对——层叠、优先级和继承——这三个最基本的 CSS 概念的理解。这些概念控制着 CSS 如何应用于 HTML 以及应用时的优先顺序。

CSS 选择器

有各种类型的 CSS 选择器，以供我们精确选出要添加样式的元素。在本文及其子文章中，我们会详细过一遍不同类型的选择器，以此窥探 CSS 选择器的运行机理。子文章包括了：

* 类型、类以及 ID 选择器
* 属性选择器
* 伪类与伪元素
* 关系选择器

盒模型

所有 CSS 都是包在盒子里的，那么理解这些盒子就是让我们能够创建 CSS 布局或排列元素的关键点了。为了接下来能完成编写复杂布局的任务，本节我们会认真看看*CSS 盒模型*，了解其原理及相关术语。

背景与边框

在这一节课中，我们将会看一下你可以用 CSS 对背景和边框进行哪些创新。通过添加渐变、背景图片和圆角，背景和边框可以解决许多 CSS 中的样式问题。

处理不同的文本方向

最近几年来，CSS 进行了演化，以更好地支持不同方向的内容，既包括自左至右，又包括自上至下（如日语）的内容——这些不同的排布方向被称作书写模式。随着你在这部分学习中不断前进并开始设计网页布局，理解书写模式将会非常有帮助，因此我们会在本文中进行介绍。

溢出的内容

这一节我们会关注 CSS 中的另一个重要的概念——溢出。溢出发生在一个盒子中包含了过多内容以致超出适当的范围时。在这篇指南中，你将学到什么是溢出以及如何处理它。

值和单位

CSS 中每一个属性都有一个取值或者一系列合理的取值。这一节，我们将了解一些最常用的取值和单位。

在 CSS 中调整大小

通过目前为止的一系列课程，你已经了解了许多使用 CSS 调整网页项目大小的方法。了解你所设计的不同特性将呈现的大小很重要，我们将在这节课中总结使用 CSS 调整大小的不同方法，并定义几个有关尺寸的术语，这将对你有所帮助。

图片、媒体和表单元素

在这一节，我们会了解 CSS 是如何处理一些特殊元素的。与常规的盒子相比，图片、其他媒体和表格元素对你使用 CSS 设置样式的能力提出了不同的要求。理解什么能够实现和什么不能够实现将会免去你一些沮丧，这节课会突出一些你需要了解的主要问题。

样式化表格

设计 HTML 表格的样式并不是多么美妙的工作，但有时却是我们都需要去做的。这篇文章通过突出一些特定的表格样式技巧，为设计好看的 HTML 表格提供了一份指南。

调试 CSS

有时在编写 CSS 的过程中，你会遇到这样一个问题：你的 CSS 并没有实现你想要的效果。这篇文章将为你提供指导，教你如何调试 CSS 问题，以及如何使用所有现代浏览器带有的开发者工具找到问题所在。

组织 CSS

当你开始处理更大的样式表和项目时，你将会发现维护一个庞大的样式表非常具有挑战性。在这篇文章中，我们将会简要了解使得 CSS 易于维护的最佳做法，以及其他人所使用的一些有助于增进可维护性的解决方案。

评估
--

想要测试一下你的 CSS 技能吗？下面这些评估将测试你对以上那些指南中的 CSS 技能的掌握。

基本的 CSS 理解

这项评估测试你对基本语法、选择器、特异性、盒子模型的掌握。

设计漂亮的信头信笺

如果你想留下良好的印象，用一张漂亮的信头信笺写一封信一定是个好的开始。在这一评估中，你将挑战创建这样一个漂亮的网络样板。

一个炫酷的盒子

在这里，你将练习使用背景和边距来创建一个吸引眼球的盒子。

参见
--

高级区块效果

这篇文章展示了盒子的小技巧，提供了一些高级特性的介绍，这些特性不适合其他类别的样式，比如盒子阴影、混合模式和滤镜。
CSS 布局
======

此刻，我们已经看过 CSS 的基础知识，如何设置文本的样式，以及如何设置和操作内容所在的框。现在是时候看看如何把你的盒子放在与视口相关的正确位置上。我们已经涵盖了必要的先决条件，所以我们现在可以深入到 CSS 布局，查看不同的显示设置，涉及浮动和定位的传统布局方法，以及像 flexbox 这样的现代布局工具。

前提条件：
-----

在开始前，你应该已经具备：

1. 对 HTML 的基础了解，在Introduction to HTML部分讨论过的。
2. 一定的 CSS 基础，在Introduction to CSS部分讨论过的。
3. 了解如何样式化盒子模型.

**备注：** 如果你在一台电脑/平板电脑/其他设备上工作，而你没有能力创建自己的文件，你可以尝试（大部分）在线编码程序中的代码示例，如 JSBin 或 Glitch 。

指南
--

这些文章将提供在 CSS 中可用的基本布局工具和技术的指导。

介绍 CSS 布局

本文将重述一些我们在之前的模块中已经涉及的 CSS 布局功能——例如不同的 `display` 值——并介绍我们将在本单元中涵盖的一些概念。

正常布局流

这篇文章介绍正常的流布局，或者说，在你没有改变默认布局规则情况下的页面元素布局方式。

弹性盒

弹性盒 (en-US) 是一种新技术，但在如今各个浏览器都广泛支持的情况下，它已经开始准备广泛应用了。弹性盒子提供了工具，允许快速创建曾经被证明用 CSS 很难实现的一些复杂，灵活的布局和功能。本文将解释所有的基本原理。

网格

网格是一个成熟的设计工具，许多现代网站布局是基于规则网格。在本文中，我们将看看基于网格的设计，以及如何使用 CSS 来创建网格——两者都通过现在的工具，和刚刚开始在浏览器中可用的新技术。

浮动

最初对于文本块中的浮动图像，`float`属性已经成为在网页上创建多个列布局的最常用工具之一。本文解释所有。

定位

定位允许你从常规文档布局流程中取出元素，并使它们具有不同的行为，例如坐在另一个之上，或始终保持在浏览器视口内的同一位置。本文解释不同的`position` 值，以及如何使用它们。

多列布局

多列布局声明提供了一种多列组织内容的方式，正如你在一些报纸中看到的那样。这篇文章介绍怎么使用这一特性。

响应式设计

随着越来越多的屏幕尺寸出现在支持 Web 的设备上，响应式 Web 设计（RWD）的概念出现了：一组允许网页改变其布局和外观以适应不同的屏幕宽度、分辨率等的实践。这一想法改变了我们为多设备 Web 设计的方式，在本文中，我们将帮助你了解掌握它所需的主要技术。

媒体查询入门指南

**媒体查询** 提供了一种仅当浏览器和设备环境与你指定的规则匹配时才应用 css 的方法，例如“viewport（视区）宽度大于 480 像素”。媒体查询是响应式 Web 设计的一个关键部分，因为它们允许你根据视区的大小创建不同的布局，但也可以用于检测有关网站运行环境的其他内容，例如用户是否使用触摸屏而不是鼠标。在本节中，你将首先了解媒体查询中使用的语法，然后在一个演示如何使简单设计具有响应性的示例中继续使用它们。

传统布局方法

网格系统是 css 布局中使用的一个非常常见的特性，在 css 网格布局之前，它们往往使用浮动或其他布局特性来实现。你可以将布局想象为一组列（例如 4、6 或 12），然后将网页内容放入这些列中。在本文中，我们将探讨这些旧方法是如何工作的，以便你了解在处理旧项目时如何使用它们。

支持旧浏览器

在本模块中，我们建议使用弹性盒和网格作为主要布局方法。但是，你的网站会遇到使用旧浏览器的访问者，或者不支持你使用的新布局方法的浏览器。在网络开发上一直有这种状况——那就是随着新特性的开发，不同的浏览器将优先支持不同的特性。本文解释了如何使用现代 web 技术而不将使用旧版本浏览器的用户拒之门外。

测试：基本布局掌握

通过布置网页来测试你对不同布局方法的知识的掌握。

参见
--

练习定位案例

在最后一篇文章中介绍了定位的基础知识，现在将讨论构建几个真实世界的例子，以说明你可以通过定位做什么样的事情。
CSS 入门概述
========

CSS（层叠样式表）用于设置和布置网页——例如，更改内容的字体、颜色、大小和间距，将其拆分为多个列，或添加动画和其他装饰功能。这个模块为你掌握 CSS 的过程提供了一个温和的开端，包括它如何工作的基础知识，语法是什么样的，以及如何开始使用它来为 HTML 添加样式。

前提
--

在开始本单元之前，你应该：

1. 基本熟悉使用计算机，并被动地使用 Web（即查看它、了解其内容）。
2. 基本工作环境的设置详见安装基本软件，并了解如何创建和管理文件，详见处理文件。
3. 熟悉 HTML 概述 章节中提到的基本 HTML 知识。

**备注：** 如果你在一个无权创建自己文件的电脑/平板/其他设备上工作，你可以在在线编程工具上尝试（大部分）代码示例，如 JSBin 或者 Glitch 等。

指南
--

该模块包含以下文章，这些文章将带你了解 CSS 的所有基本理论，并提供测试一些技能的机会。

什么是 CSS

**CSS** (Cascading Style Sheets) 使你创建外观漂亮的网页，但它如何起作用的呢？这篇文章用一个简单的语法示例解释 CSS 是什么，还包括有关该语言的一些关键术语。

CSS 入门

在本文中，我们将采用一个简单的 HTML 文档并将 CSS 应用于该文档，并在此过程中学习一些关于语言的实用内容。

CSS 的结构

现在你已经了解了 CSS 是什么以及使用它的基础知识，现在是时候更深入地了解语言本身的结构。在这里，我们已经遇到了讨论过的许多概念; 如果你发现任何令人困惑的概念，你可以回到这个回顾。

CSS 如何工作

我们已经学习了 CSS 基础理论：CSS 是什么以及如何编写简单的样式表。在这个课程中，我们将看看浏览器如何使用 CSS 和 HTML 并将其转换为网页。

测验
--

以下测验将检验你对上述指南中涵盖的 CSS 基础知识的理解。

为传记页面添加样式

借助你在最近几篇文章中学到的内容，你应该发现可以使用 CSS 格式化简单的文本文档，从而为它们添加自己的样式。该测验为你提供了这样做的机会。