diff --git a/files/zh-cn/learn/getting_started_with_the_web/html_basics/index.md b/files/zh-cn/learn/getting_started_with_the_web/html_basics/index.md index a9655b09e09c47..1d0b1f9bd7502c 100644 --- a/files/zh-cn/learn/getting_started_with_the_web/html_basics/index.md +++ b/files/zh-cn/learn/getting_started_with_the_web/html_basics/index.md @@ -230,7 +230,7 @@ Web 上的许多内容都是列表,HTML 有一些特别的列表元素。标 现在就为页面添加一个链接吧。 -## 小结 +## 总结 如果你一直跟着这篇文章里的指导做的话,你应该完成了一个像下面这样的页面(也可以[查看这里](https://mdn.github.io/beginner-html-site/)): diff --git a/files/zh-cn/learn/getting_started_with_the_web/javascript_basics/beginner-site-scripted.png b/files/zh-cn/learn/getting_started_with_the_web/javascript_basics/beginner-site-scripted.png deleted file mode 100644 index bc14a57a59238e..00000000000000 Binary files a/files/zh-cn/learn/getting_started_with_the_web/javascript_basics/beginner-site-scripted.png and /dev/null differ diff --git a/files/zh-cn/learn/getting_started_with_the_web/javascript_basics/index.md b/files/zh-cn/learn/getting_started_with_the_web/javascript_basics/index.md index 785c8aa70a6d1d..a8ba6332566b46 100644 --- a/files/zh-cn/learn/getting_started_with_the_web/javascript_basics/index.md +++ b/files/zh-cn/learn/getting_started_with_the_web/javascript_basics/index.md @@ -1,123 +1,123 @@ --- title: JavaScript 基础 slug: Learn/Getting_started_with_the_web/JavaScript_basics +l10n: + sourceCommit: 9e8b77593a626b1e0765494e4928b8f4a5c2d9bd --- {{LearnSidebar}} {{PreviousMenuNext("Learn/Getting_started_with_the_web/CSS_basics", "Learn/Getting_started_with_the_web/Publishing_your_website", "Learn/Getting_started_with_the_web")}} -JavaScript 是一门编程语言,可为网站添加交互功能(例如:游戏、动态样式、动画以及在按下按钮或收到表单数据时做出的响应等)。本文介绍了 JavaScript 的精彩之处和主要用途。 +JavaScript 是一门为网站添加交互性的编程语言。交互性体现在游戏、点击按钮或输入表单时的响应行为;动态的样式;动画,等等。本文将帮助你入门 JavaScript,并进一步加深你对 JavaScript 所能实现的功能的理解。 ## JavaScript 到底是什么? -{{Glossary("JavaScript")}}(缩写:JS)是一门完备的动态编程语言。当应用于 {{Glossary("HTML")}} 文档时,可为网站提供动态交互特性。由布兰登·艾克(Brendan Eich,Mozilla 项目、Mozilla 基金会和 Mozilla 公司的联合创始人)发明。 +{{Glossary("JavaScript")}} 是一门为网站添加交互性的强有力的编程语言。由布兰登·艾克发明。 -JavaScript 的应用场合极其广泛,简单到幻灯片、照片库、浮动布局和响应按钮点击,复杂到游戏、2D/3D 动画、大型数据库驱动程序等等。 +JavaScript 是一门多功能的、新手友好的编程语言。随着经验的积累,你将能够创建游戏、2D 和 3D 图形动画、全面的数据库驱动应用程序,等等。 -JavaScript 相当简洁,却非常灵活。开发者们基于 JavaScript 核心编写了大量实用工具,可以使 开发工作事半功倍。其中包括: +JavaScript 本身相对简洁,但非常灵活。开发者在核心 JavaScript 语言的基础上编写了各种工具,让你能以最小的努力解锁大量的功能。这些工具包括: -- 浏览器应用程序接口({{Glossary("API","API")}})——浏览器内置的 API 提供了丰富的功能,比如:动态创建 HTML 和设置 CSS 样式、从用户的摄像头采集处理视频流、生成 3D 图像与音频样本等等。 -- 第三方 API——让开发者可以在自己的站点中整合其他内容提供者(Twitter、Facebook 等)提供的功能。 -- 第三方框架和库——用来快速构建网站和应用。 +- Web 浏览器内置的应用程序编程接口({{Glossary("API","API")}}),提供了丰富的功能,例如:动态创建 HTML 和设置 CSS 样式;从用户的摄像头采集和处理视频流、生成 3D 图形和音频样本。 +- 允许开发者将来自其他内容提供商(如 [Disqus](https://disqus.com/)、Facebook)的功能整合到自己的网站中的第三方 API。 +- 能够应用于 HTML 加速网站和应用程序开发的第三方框架和库。 -本节是一篇 JavaScript 简介,因此这个阶段不会对 JavaScript 语言和上述工具做过多的介绍。之后可以到 [JavaScript 学习区](/zh-CN/docs/Learn/JavaScript) 和 MDN 的其他地方学习更多细节。 +作为一篇 JavaScript 的简要介绍,阐述核心 JavaScript 和上述的工具之间的区别超出了本文的范围。你可以在 MDN 的 [JavaScript 学习区](/zh-CN/docs/Learn/JavaScript),以及 MDN 的其余部分了解更多信息。 -下面对语言核心做一个不完整介绍,期间还可以接触到一些浏览器 API 特性。 +接下来将介绍核心语言的一些方面,并提供体验一些浏览器 API 特性的机会。祝你玩得开心! ## “Hello World!”示例 -读到这里你一定很激动,诚然——JavaScript 是最振奋人心的 Web 技术之一,而且在娴熟驾驭之后,你的网站在功能和创新力上将达到一个新的维度。 +JavaScript 是最流行的现代 Web 技术之一。随着 JavaScript 技能的增长,你的网站在功能和创新力上将达到一个新的维度。 -然而,JavaScript 比 HTML 和 CSS 学习起来更加复杂一点,所以必须一步一个脚印地学习。首先,来看看如何在页面中添加一些基本的 JavaScript 脚本来建造一个“Hello world!”示例([一切始于 Hello World](https://zh.wikipedia.org/wiki/Hello_World))。 +然而,熟练掌握 JavaScript 比熟练掌握 HTML 和 CSS 要更有挑战。你必须从简单的开始,然后逐步前进。首先,来看看如何在页面中添加 JavaScript 完成 _Hello world!_ 示例(_Hello world!_ 是[标准的介绍性编程示例](https://zh.wikipedia.org/wiki/Hello_World))。 > [!WARNING] -> 如果你没有完成之前的课程实践,可下载 [上一章节示例的压缩包](https://github.com/roy-tian/learning-area/raw/master/extras/getting-started-web/beginner-html-site-styled.zip) 并在本地解压作出发点。 +> 如果你没有完成之前的课程,请先[下载这个示例代码](https://codeload.github.com/mdn/beginner-html-site-styled/zip/refs/heads/gh-pages),把示例代码当作起始点。 -1. 首先,打开你的测试站点,创建一个名为 `scripts` 的文件夹。然后在其中创建一个名为 main.js 的文件。 -2. 下一步,在 `index.html` 文件\ 标签前的新行添加以下代码。 +1. 打开测试站点的目录,创建一个名为 `scripts` 的新目录。然后在 scripts 目录中创建一个名为 `main.js` 的新文件,并保存。 +2. 打开 `index.html` 文件,在结束标签 `` 前添加下列代码: ```html - + ``` -3. 与 CSS 的 {{htmlelement("link")}} 元素类似,它将 JavaScript 引入页面以作用于 HTML(以及 CSS 等页面上所有内容): -4. 现在将以下代码添加到 `main.js` 文件中: +3. 与 CSS 的 {{htmlelement("link")}} 元素的功能类似,它将 JavaScript 引入以作用于 HTML(以及 CSS 和页面上的任何其他内容)。 +4. 将下列代码添加到 `scripts/main.js` 文件: ```js - let myHeading = document.querySelector("h1"); + const myHeading = document.querySelector("h1"); myHeading.textContent = "Hello world!"; ``` -5. 最后,保存 HTML 和 JavaScript 文件,用浏览器打开 `index.html`。可以看到如下内容:![](hello-world.png) +5. 确认保存了 HTML 和 JavaScript 文件。然后在浏览器中打开 `index.html`。你应该看到类似的内容: + +![“hello world”标题,下面是 firefox 标志](hello-world.png) > [!NOTE] -> 我们将 {{htmlelement("script")}} 放在 HTML 文件的底部附近的原因是浏览器会按照代码在文件中的顺序加载 HTML。如果先加载的 JavaScript 期望修改其下方的 HTML,那么它可能由于 HTML 尚未被加载而失效。因此,将 JavaScript 代码放在 HTML 页面的底部附近通常是最好的策略。 +> 上面将 {{htmlelement("script")}} 元素放在 HTML 文件的底部附近的原因是**浏览器会按照代码在文件中的顺序进行读取**。 +> +> 如果 JavaScript 先加载,并期望操纵还未加载的 HTML,可能会出现问题。将 JavaScript 放在 HTML 页面的底部附近是一种解决方案。想要了解更多的替代方案,参见[脚本加载策略](/zh-CN/docs/Learn/JavaScript/First_steps/What_is_JavaScript#脚本加载策略)。 ### 发生了什么? -JavaScript 把页面的标题改成了“Hello world!” 。首先用 {{domxref("Document.querySelector", "querySelector()")}} 函数获取标题的引用,并把它储存在 `myHeading` 变量中。这与 CSS 选择器的用法非常相像:若要对某个元素进行操作,首先得选择它。 +使用 JavaScript 把标题文本改成了 _Hello world!_。用 {{domxref("Document.querySelector", "querySelector()")}} 函数获取标题的引用,然后把它储存在 `myHeading` 变量中。这与 CSS 选择器的用法非常相像。若要对某个元素进行操作,首先得选择它。 -之后,把 `myHeading` 变量的属性 {{domxref("Node.textContent", "textContent")}} (标题内容)修改为“Hello world!” 。 +接着,把 `myHeading` 变量的 {{domxref("Node.textContent", "textContent")}} 属性(表示标题内容)的值设置为 _Hello world!_。 > [!NOTE] -> 上面用到的两个函数都来自 [文档对象模型 (DOM) API](/zh-CN/docs/Web/API/Document_Object_Model),均用于控制文档。 +> 在这个练习中用到的两个特性都来自[文档对象模型(DOM)API](/zh-CN/docs/Web/API/Document_Object_Model)(DOM API 用于操纵文档)。 -## JavaScript 快速入门 +## JavaScript 速成课程 -我们来学习一些 JavaScript 的核心特性,从而更好地理解它的运行机制。学习这些知识很有意义,因为这些原理普遍适用于所有编程语言,掌握好它们,可以做到融会贯通。 +为了让你更好地理解 JavaScript 的运行机制,我们会解释一些语言的核心特性。值得注意的是,这些特性是所有编程语言的共性。如果掌握了这些基础知识,你也可以开始用其他语言写代码。 > [!WARNING] -> 学习本节时,请尝试将示例代码输入到 JavaScript 控制台里看看会发生什么。JavaScript 控制台的更多信息请查看 [浏览器开发者工具](/zh-CN/Learn/Discover_browser_developer_tools)。 +> 学习本文时,请尝试在 JavaScript 控制台中输入示例代码行,看看会发生什么。在[探索浏览器开发者工具](/zh-CN/docs/Learn/Common_questions/Tools_and_setup/What_are_browser_developer_tools)中了解更多有关 JavaScript 控制台的信息。 -### 变量(Variable) +### 变量 -{{Glossary("Variable", "变量")}} 是存储值的容器。要声明一个变量,先输入关键字 `let` 或 `var`,然后输入合适的名称: +{{Glossary("Variable", "变量")}}是存储值的容器。要声明变量,先输入 [`let`](/zh-CN/docs/Web/JavaScript/Reference/Statements/let) 关键字,然后输入变量名: ```js let myVariable; ``` -> [!NOTE] -> 行末的分号表示当前语句结束,不过只有在单行内需要分割多条语句时,这个分号才是必须的。然而,一些人认为每条语句末尾加分号是一种好的风格。分号使用规则的更多细节请参阅 [JavaScript 分号使用指南](http://news.codecademy.com/your-guide-to-semicolons-in-javascript/)(英文页面)。 +行尾的分号表示语句结束。仅当你需要在单行内分隔多条语句时,分号才是必须的。然而,一些人认为每条语句末尾加分号是最佳实践。对于何时应该使用、何时不应该使用分号有其他的规则。在[你的 JavaScript 分号指南](https://www.codecademy.com/resources/blog/your-guide-to-semicolons-in-javascript/)中了解更多细节。 -> [!NOTE] -> 几乎任何内容都可以作为变量名,但还是有一些限制(请参阅 [变量命名规则](/zh-CN/docs/Web/JavaScript/Guide/Grammar_and_Types#变量))。如果你不确定,还可以 [验证变量名](https://mothereff.in/js-variables) 是否有效。 +变量名几乎可以任意取,但有一些限制(参见[命名规则小节](/zh-CN/docs/Web/JavaScript/Guide/Grammar_and_types#变量))。如果你不确定,还可以[验证变量名](https://mothereff.in/js-variables)是否有效。 -> [!NOTE] -> JavaScript 对大小写敏感,`myVariable` 和 `myvariable` 是不同的。如果代码出现问题了,先检查一下大小写! +JavaScript 对大小写敏感。这意味着 `myVariable` 和 `myvariable` 是不同的。如果代码中有问题,检查一下大小写! -> [!NOTE] -> 想要了解更多关于 `var` 和 `let` 的不同点,可以参阅 [var 与 let 的区别](/zh-CN/docs/Learn/JavaScript/First_steps/Variables#var_与_let_的区别)。 - -变量定义后可以进行赋值: +声明变量后,你可以给它赋值: ```js -myVariable = "李雷"; +myVariable = "鲍勃"; ``` -也可以将定义、赋值操作写在同一行: +你也可以在同一行执行声明和赋值操作: ```js -let myVariable = "李雷"; +let myVariable = "鲍勃"; ``` -可以直接通过变量名取得变量的值: +你可以通过变量名获取值: ```js myVariable; ``` -变量在赋值后是可以更改的: +给变量赋值后,你可以修改变量的值: ```plain -let myVariable = '李雷'; -myVariable = '韩梅梅'; +let myVariable = "鲍勃"; +myVariable = "斯蒂夫"; ``` -注意变量可以有不同的 [数据类型](/zh-CN/docs/Web/JavaScript/Data_structures) : +注意变量可以存储不同[数据类型](/zh-CN/docs/Web/JavaScript/Data_structures)的值: - +
@@ -127,74 +127,66 @@ myVariable = '韩梅梅'; - + - + - - + + - + - - + + - +
变量
{{Glossary("String")}}{{Glossary("String", "字符串")}} - 字符串(一串文本):字符串的值必须用引号(单双均可,必须成对)括起来。 + 字符串就是文本序列。用单引号或双引号括起来的值就是字符串。 let myVariable = '李雷';let myVariable = '鲍勃'; 或者
let myVariable = "鲍勃";
{{Glossary("Number")}}数字:无需引号。{{Glossary("Number", "数字")}}数字周围没有引号。 let myVariable = 10;
{{Glossary("Boolean")}}{{Glossary("Boolean", "布尔")}} - 布尔值(真 / 假): true/false 是 JS - 里的特殊关键字,无需引号。 + 真/假值。单词 true/false 是不需要引号的特殊关键字。 let myVariable = true;
{{Glossary("Array")}}数组:用于在单一引用中存储多个值的结构。{{Glossary("Array", "数组")}}让你在单一引用中存储多个值的结构。 - let myVariable = [1, '李雷', '韩梅梅', 10];
元素引用方法:myVariable[0], - myVariable[1] …… + let myVariable = [1,'鲍勃','斯蒂夫',10];
像这样引用数组成员:myVariable[0]myVariable[1],等等。
{{Glossary("Object")}}{{Glossary("Object", "对象")}} - 对象:JavaScript 里一切皆对象,一切皆可储存在变量里。这一点要牢记于心。 + 可以是任何内容。JavaScript 里的一切都是对象,对象能在变量中存储。这一点要牢记于心。 - let myVariable = document.querySelector('h1');
以及上面所有示例都是对象。 + let myVariable = document.querySelector('h1');
上面的示例都是。
-那么变量有什么用呢?我们说,编程时它们无所不在。如果值无法改变,那么就无法做任何动态的工作,比如发送个性化的问候,或是改变在图片库当前展示的图片。 +那么变量有什么用呢?编程时变量无处不在。如果值不能修改,那么就无法做任何动态的工作,比如个性化的问候,或是改变图片库中展示的图片。 ### 注释 -类似于 CSS,JavaScript 中可以添加注释。 +注释是和代码一起的文本片段。浏览器会忽略注释。类似于 CSS,JavaScript 中可以添加注释。 ```js /* -这里的所有内容 -都是注释。 +这里的所有内容都是注释。 */ ``` -如果注释只有一行,可以更简单地将注释放在两个斜杠之后,就像这样: +如果注释只有一行,将注释放在两个斜杠之后也是个选择,就像这样: ```js -// 这是一条注释。 +// 这是注释。 ``` ### 运算符 -{{Glossary("Operator","运算符")}} 是一类数学符号,可以根据两个值(或变量)产生结果。以下表格中介绍了一些最简单的运算符,可以在浏览器控制台里尝试一下后面的示例。 - -> [!NOTE] -> 这里说“根据**两个**值(或变量)产生结果”是不严谨的,计算两个变量的运算符称为“二元运算符”,还有一元运算符和三元运算符,下表中的“取非”就是一元运算符。 +{{Glossary("Operator","运算符")}}是一种基于两个值(或变量)生成对应结果的数学符号。在下列表格中,介绍了一些最简单的运算符以及一些对应的示例,可以在 JavaScript 控制台中尝试这些示例。 - +
@@ -206,103 +198,99 @@ myVariable = '韩梅梅'; - + - - + + - - + + - + - + - + - + - + - - - - - -
运算符
将两个数字相加,或拼接两个字符串。将两个数字相加或拼接两个字符串。 + - 6 + 9;
"Hello " + "world!";
+ 6 + 9;
'Hello ' + 'world!';
减、乘、除这些运算符操作与基础算术一致。只是乘法写作星号,除法写作斜杠。-, *, /这些运算符的作用与基础算术一致。-*/ 9 - 3;
8 * 2; //乘法在 JS 中是一个星号
9 / 3;
赋值运算符为变量赋值(你之前已经见过这个符号了)赋值你已经见过了:为变量赋值。 =let myVariable = '李雷';let myVariable = '鲍勃';
等于严格相等 - 测试两个值是否相等,并返回一个 true/false - (布尔)值。 + 测试两个值是否相等以及是否是相同的数据类型,并返回一个 true/false(布尔)结果。 ====== - let myVariable = 3;
myVariable === 4; // false
+ let myVariable = 3;
myVariable === 4;
不等于非、不等于 - 和等于运算符相反,测试两个值是否不相等,并返回一个 - true/false (布尔)值。 + 返回和先前逻辑上相反的值。非将 true 变为 false,等等。当它和相等运算符一起使用时,否定运算符测试两个值是否相等。 !==!!== - let myVariable = 3;
myVariable !== 3; // - false
-
取非返回逻辑相反的值,比如当前值为真,则返回 false! - 原式为真,但经取非后值为 false
let myVariable = 3;
!(myVariable === 3); // false
+

+ 对于“非”,基本表达式是 true,但结果返回的是 false,因为我们否定了这个值: +

+

+ let myVariable = 3;
!(myVariable === 3);
+

+

+ “不等于”用不同的语法得出了基本上一样的结果。这里测试“myVariable 不等于 3”。返回 false,因为 myVariable 等于 3: +

+

+ let myVariable = 3;
myVariable !== 3;
+

-运算符种类远不止这些,不过目前上表已经够用了。完整列表请参阅 [表达式和运算符](/zh-CN/docs/Web/JavaScript/Reference/Operators)。 +运算符种类远不止这些,不过目前上表已经够用了。在[表达式和运算符](/zh-CN/docs/Web/JavaScript/Reference/Operators)中了解完整列表。 > [!NOTE] -> 不同类型数据之间的计算可能出现奇怪的结果,因此必须正确引用变量,才能得出预期结果。比如在控制台输入 `"35" + "25"`,为什么不能得到 `60`?因为引号将数字转换成了字符串,所以结果是连接两个字符串而不是把两个数字相加。输入 `35 + 25` 才能得到正确结果。 +> 执行计算时,混用数据类型可能出现一些奇怪的结果。注意要正确地引用变量,然后得到预期的结果。比如在控制台输入 `"35" + "25"`,为什么没有得到预期的结果?因为引号将数字转换成了字符串,所以结果是拼接两个字符串而不是把两个数字相加。如果输入 `35 + 25`,你就会得到两个数字的和。 ### 条件语句 -条件语句是一种代码结构,用来测试表达式的真假,并根据测试结果运行不同的代码。一个常用的条件语句是 `if ... else`。下面是一个示例: +条件语句是用来测试表达式的真假的代码结构。一个常用的条件语句是 `if...else` 语句。例如: ```js let iceCream = "chocolate"; if (iceCream === "chocolate") { - alert("我最喜欢巧克力冰淇淋了。"); + alert("我最喜欢巧克力冰淇淋了!"); } else { alert("但是巧克力才是我的最爱呀……"); } ``` -`if ( ... )` 中的表达式进行测试,用(上文所提到的)等于运算符来比较变量 `iceCream` 与字符串 `'chocolate'` 是否相等。如果返回 `true`,则运行第一个代码块;如果返回 `false`,则跳过第一块直接运行 `else` 之后的第二个代码块。 +`if ()` 中的表达式是一个测试。用(上文所提到的)严格相等运算符来比较 `iceCream` 变量与 `chocolate` 字符串是否相等。如果返回 `true`,则运行第一个代码块;如果返回 `false`,则运行 `else` 关键字之后的第二个代码块。 -### 函数(Function) +### 函数 -{{Glossary("Function", "函数")}} 用来封装可复用的功能。如果没有函数,一段特定的操作过程用几次就要重复写几次,而使用函数则只需写下函数名和一些简短的信息。之前已经涉及过一些函数,比如: +{{Glossary("Function", "函数")}}是一种将你希望重复使用的功能封装起来的方式。你可以将一段代码定义为一个函数,当你在代码中调用该函数名时,它会执行。这是一种避免重复编写相同代码的好方式。你已经看到了一些函数的使用示例了。比如: ```js let myVariable = document.querySelector("h1"); ``` ```js -alert("hello!"); +alert("你好!"); ``` -`document.querySelector` 和 `alert` 是浏览器内置的函数,随时可用。 +`document.querySelector` 和 `alert` 是浏览器内置的函数。 -如果代码中有一个类似变量名后加小括号 `()` 的东西,很可能就是一个函数。函数通常包括{{Glossary("Argument", "参数")}},参数中保存着一些必要的数据。它们位于括号内部,多个参数之间用逗号分开。 +如果你发现有个像变量名,但后面跟着小括号——`()`——的东西,它很可能是函数。函数通常接收{{Glossary("Argument", "参数")}}:函数用来执行特定的任务。参数位于小括号内,多个参数之间用逗号分开。 -比如, `alert()` 函数在浏览器窗口内弹出一个警告框,还应为其提供一个字符串参数,以告诉它警告框里要显示的内容。 +比如, `alert()` 函数在浏览器窗口内弹出一个警告框,但还应为其提供一个字符串参数,告诉它警告框里要显示的内容。 -好消息是:人人都能定义自己的函数。下面的示例是为两个参数进行乘法运算的函数: +你也可以定义你自己的函数。在下面的例子中,我们创建了一个接收两个数字参数的函数,并对这两个参数做乘法: ```js function multiply(num1, num2) { @@ -311,7 +299,7 @@ function multiply(num1, num2) { } ``` -尝试在控制台运行这个函数,不妨多试几组参数,比如: +尝试在控制台中运行这个函数;然后多试几组参数。比如: ```js multiply(4, 7); @@ -319,46 +307,48 @@ multiply(20, 20); multiply(0.5, 3); ``` -> **备注:** [`return`](/zh-CN/docs/Web/JavaScript/Reference/Statements/return) 语句告诉浏览器当前函数返回 `result` 变量。这是一点很有必要,因为函数内定义的变量只能在函数内使用。这叫做变量的 {{Glossary("Scope", "作用域")}}。(详见 [变量作用域](/zh-CN/docs/Web/JavaScript/Guide/Values,_variables,_and_literals#Variable_scope)。) +> **备注:** [`return`](/zh-CN/docs/Web/JavaScript/Reference/Statements/return) 语句告诉浏览器将 `result` 变量返回到函数外面。这一点很有必要,因为函数内定义的变量只能在函数内使用。这叫做变量的{{Glossary("Scope", "作用域")}}。(阅读更多有关[变量的作用域](/zh-CN/docs/Web/JavaScript/Guide/Grammar_and_types#变量的作用域)的内容。) ### 事件 -事件能为网页添加真实的交互能力。它可以捕捉浏览器操作并运行一些代码做为响应。最简单的事件是[点击事件](/zh-CN/docs/Web/API/Element/click_event),鼠标的点击操作会触发该事件。可尝试将下面的代码输入到控制台,然后点击页面的任意位置: +事件处理器能为网页添加真正的交互。它们是监听浏览器活动的代码块,并在响应中运行代码。最明显的例子就是处理[点击事件](/zh-CN/docs/Web/API/Element/click_event),当你用鼠标点击时,浏览器会触发该事件。作为演示,在控制台中输入下面的代码,然后点击网页的任意位置: ```js document.querySelector("html").addEventListener("click", function () { - alert("别戳我,我怕疼。"); + alert("别戳我,我怕疼!"); }); ``` -将事件与元素绑定有许多方法。在这里选用了 {{htmlelement("html")}} 元素,然后调用了它的 [`addEventListener()`](/zh-CN/docs/Web/API/EventTarget/addEventListener) 方法,将事件名称(`'click'`)以及其回调函数(当事件发生时,调用该函数)传入该函数中作为调用参数。 +将事件处理器与元素绑定有许多方法。这里我们选择了 {{htmlelement("html")}} 元素,然后调用了它的 [`addEventListener()`](/zh-CN/docs/Web/API/EventTarget/addEventListener) 函数,并传递要监听的事件名(`'click'`)和事件发生时要运行的函数。 -刚刚我们传递给 `addEventListener()` 的函数被称为*匿名函数*,因为它没有名字。匿名函数还有另一种我们称之为*箭头函数*的写法,箭头函数使用 `() =>` 代替 `function ()`: +刚刚我们传递给 `addEventListener()` 的函数被称为*匿名函数*,因为它没有名字。匿名函数还有另一种书写方式,我们称之为*箭头函数*。箭头函数使用 `() =>` 而不是 `function ()`: ```js document.querySelector("html").addEventListener("click", () => { - alert("别戳我,我怕疼。"); + alert("别戳我,我怕疼!"); }); ``` -## 完善示例网页 +## 完善示例网站 -现在你已经具备了一些 JavaScript 基础,下面来为示例网页添加一些更酷的特性。 +现在你已经具备了一些 JavaScript 基础,下面让我们为示例网站添加一些新特性。 + +在继续下面的内容之前,将 `main.js` 文件中的内容都删掉——即你在“Hello world!”示例中添加的内容——并保存这个空文件。要是不这样做的话,已经存在的代码将会与你下面要写的新代码产生冲突。 ### 添加一个图像切换器 -这里将用新的 DOM API 为网页添加另一张图片,并用 JavaScript 使图片在点击时进行切换。 +在本小节,你将会学习如何使用 JavaScript 和 DOM API 特性交替显示两张图片。当用户点击图片时进行切换。 -1. 首先,找到另一张你想要在你的页面上展示的图片,且尺寸与第一张图片尽可能相同。 -2. 将这张图片储存在你的`images`目录下。 -3. 将图片重命名为'firefox2.png'(去掉引号)。 -4. 打开 `main.js` 文件,输入下面的 JavaScript 代码 ( 请删除刚才的 "hello world" 脚本): +1. 选择一张你想在页面上展示的图片。理想情况下,这张图片的尺寸与之前添加的图片的尺寸尽可能相同。 +2. 将这张图片保存在 `images` 目录中。 +3. 将这张图片重命名为 _firefox2.png_。 +4. 将下列的 JavaScript 代码添加到 `main.js` 文件: ```js - let myImage = document.querySelector("img"); + const myImage = document.querySelector("img"); - myImage.onclick = function () { - let mySrc = myImage.getAttribute("src"); + myImage.onclick = () => { + const mySrc = myImage.getAttribute("src"); if (mySrc === "images/firefox-icon.png") { myImage.setAttribute("src", "images/firefox2.png"); } else { @@ -367,59 +357,59 @@ document.querySelector("html").addEventListener("click", () => { }; ``` -5. 保存所有文件并用浏览器打开 `index.html` 。点击图片可以发现它能够切换了! +5. 保存所有文件并用浏览器打开 `index.html`。现在,当你点击图片时,会切换成另一张。 -这里首先把 {{htmlelement("img")}} 元素的引用存放在 `myImage` 变量里。然后将这个变量的 `onclick` 事件与一个匿名函数绑定。每次点击图片时: +发生的事情是这样的。把 {{htmlelement("img")}} 元素的引用存储在 `myImage` 变量中。接下来,让它的 `onclick` 事件处理器属性等于一个无名函数(“匿名”函数)。这样每次点击图片时: 1. 获取这张图片的 `src` 属性值。 -2. 用一个条件句来判断 `src` 的值是否等于原始图像的路径: +2. 用一个条件句来判断 `src` 的值是否等于原始图片的路径: - 1. 如果是,则将 `src` 的值改为第二张图片的路径,并在 {{htmlelement("img")}} 内加载该图片。 + 1. 如果是,则将 `src` 的值改为第二张图片的路径,在 {{htmlelement("img")}} 内强制加载第二张图片。 2. 如果不是(意味着它已经修改过), 则把 `src` 的值重新设置为原始图片的路径,即原始状态。 ### 添加个性化欢迎信息 -下面来添加另一段代码,在用户初次进入站点时将网页的标题改成一段个性化欢迎信息(即在标题中添加用户的名字)。名字信息会由 [Web Storage API](/zh-CN/docs/Web/API/Web_Storage_API) 保存下来,即使用户关闭页面之后再重新打开,仍可得到之前的信息。还会添加一个选项,可以根据需要改变用户名字以更新欢迎信息。 +接下来,让我们在用户第一次访问站点时将页面标题修改为个性化欢迎信息。这个欢迎消息会一直存在。名字信息会由 [Web 存储 API](/zh-CN/docs/Web/API/Web_Storage_API) 保存下来,即使用户关闭页面之后再重新打开。还会添加一个选项,改变用户名字以更新欢迎信息。 -1. 打开 `index.html`,在 {{htmlelement("script")}} 标签**前**添加以下代码,将在页面底部显示一个“切换用户”字样的按钮: +1. 打开 `index.html`,在 {{htmlelement("script")}} 元素前添加下列代码: ```html - + ``` -2. 将以下 JavaScript 代码原封不动添加到 `main.js` 文件底部,将获取新按钮和标题的引用,并保存至变量中: +2. 打开 `main.js`,将下列代码原封不动地添加到文件的底部。将获取新按钮和标题的引用,并存储到变量中: ```js let myButton = document.querySelector("button"); let myHeading = document.querySelector("h1"); ``` -3. 然后添加以下函数来设置个性化欢迎信息。(函数需要在调用后生效,下文中提供了两种对该函数的调用方式) +3. 添加下列设置个性化欢迎信息的函数。现在什么都还没发生,但一会就会发生了。 ```js function setUserName() { - let myName = prompt("请输入你的名字。"); + const myName = prompt("Please enter your name."); localStorage.setItem("name", myName); - myHeading.textContent = "Mozilla 酷毙了," + myName; + myHeading.textContent = `Mozilla is cool, ${myName}`; } ``` - 该函数首先调用了 [`prompt()`](/zh-CN/docs/Web/API/Window.prompt) 函数,与 `alert()` 类似会弹出一个对话框。但是这里需要用户输入数据,并在确定后将数据存储在 `myName` 变量里。接下来将调用 [`localStorage`](/zh-CN/docs/Web/API/Window/localStorage) API,它可以将数据存储在浏览器中供后续获取。这里用 `localStorage` 的 `setItem()` 函数来创建一个`'name'` 数据项,并把 `myName` 变量复制给它。最后将 `textContent` 属性设置为一个欢迎字符串加上这个新设置的名字。 + `setUserName()` 函数包含一个 [`prompt()`](/zh-CN/docs/Web/API/Window/prompt) 函数,与 `alert()` 类似会弹出一个对话框。`prompt()` 函数的功能更多,需要用户输入数据,并在用户点击*确定*后将数据存储在一个变量中。在这个例子里,我们要求用户输入一个名字。接下来,代码调用 `localStorage` API,它允许我们将数据存储在浏览器中并供后续获取。我们使用 `localStorage` 的 `setItem()` 函数创建并存储一个`'name'` 的数据项,并将它的值设置为包含用户名的 `myName` 变量。最后将标题的 `textContent` 属性设置为带有用户新设置的名字的字符串。 -4. 接下来,添加以下的 `if ... else` 块。我们可以称之为初始化代码,因为它在页面初次读取时进行构造工作: +4. 在函数声明的后面添加下列条件语句块。我们称之为初始化代码,因为它在初次加载时开始工作。 ```js if (!localStorage.getItem("name")) { setUserName(); } else { - let storedName = localStorage.getItem("name"); - myHeading.textContent = "Mozilla 酷毙了," + storedName; + const storedName = localStorage.getItem("name"); + myHeading.textContent = `Mozilla is cool, ${storedName}`; } ``` - 这里首次使用了取非运算符(逻辑非,用 `!` 表示)来检测 `'name'` 数据是否存在。若不存在,调用 `setUserName()` 创建。若存在(即用户上次访问时设置过),调用 `getItem()` 获取保存的名字,像上文的 `setUserName()` 那样设置 `textContent`。 + 这里的第一行使用取非运算符(逻辑非,用 `!` 表示)检测 `name` 数据是否存在。若不存在,调用 `setUserName()` 创建 `name` 数据。若存在(即用户上次访问时设置了用户名),调用 `getItem()` 获取保存的名字,然后像 `setUserName()` 中那样设置标题的 `textContent`。 -5. 最后,为按钮设置 onclick 事件处理器。按钮按下时运行 setUserName() 函数。这样用户就可以通过按这个按钮来自由设置新名字了: +5. 设置按钮的 `onclick` 事件处理器。按钮点击时,运行 `setUserName()` 函数。这样用户就可以通过点击按钮设置新名字了。 ```js myButton.onclick = function () { @@ -427,38 +417,43 @@ document.querySelector("html").addEventListener("click", () => { }; ``` -第一次访问网页时,页面将询问用户名并发出一段个性化的信息。可随时点击按钮来改变用户名。告诉你一个额外的福利,因为用户名是保存在 `localStorage` 里的,网页关闭后也不会丢失,所以重新打开浏览器时所设置的名字信息将依然存在:) - -### 用户名为 null? +### 用户名为 null? -运行示例代码,弹出输入用户名的对话框,试着按下 取消 按钮。此时标题会显示为“Mozilla 酷毙了,null”。这是因为取消提示对话框后值将设置为 `null`,这是 JavaScript 中的一个特殊值,表示引用不存在。 +运行示例代码,弹出输入用户名的对话框,试着点击*取消*按钮。此时标题会显示为 _Mozilla is cool, null_。这是因为取消提示对话框后值将设置为 [`null`](/zh-CN/docs/Web/JavaScript/Reference/Operators/null)。_null_ 是 JavaScript 中的一个特殊值,表示引用的值不存在。 -也可以不输入任何名字直接按 确认,你的标题会显示为“Mozilla 酷毙了,”,原因么显而易见。 +也可以不输入任何名字直接点击*确认*,你的标题会显示为 _Mozilla is cool,_,原因么显而易见。 -要避免这些问题,应该更新 `setUserName()` 来检查用户是否输入了 `null` 或者空名字: +要避免这些问题,应该检查用户没有输入空名字。更新 `setUserName()` 为: ```js function setUserName() { - let myName = prompt("请输入你的名字。"); + const myName = prompt("Please enter your name."); if (!myName) { setUserName(); } else { localStorage.setItem("name", myName); - myHeading.textContent = "Mozilla 酷毙了," + myName; + myHeading.textContent = `Mozilla is cool, ${myName}`; } } ``` -用人话说就是:如果 `myName` 没有值或值为 `null`,就再次从头运行`setUserName()`。如果有值(上面的表达式结果不为真),就把值存储到 `localStorage` 并且设置标题。 +翻译一下就是:如果 `myName` 没有值,就再次从头运行`setUserName()`。如果有值(如果上面的表达式不为真),就把值存储到 `localStorage` 并设置为标题文本。 + +## 总结 + +如果你一直跟着这篇文章里的指导做的话,你应该完成了一个像下面这样的页面。你也可以[查看我们的版本](https://mdn.github.io/beginner-html-site-scripted/)。 -## 小结 +![创建元素后 HTML 页面最终的样子:一个标题、居中的大标志、内容和一个按钮](website-screen-scripted.png) -如果你按部就班完成本文的实践,那么最终可以得到以下页面(可以 [查看我们的版本](https://roy-tian.github.io/learning-area/extras/getting-started-web/beginner-html-site-scripted/)): +如果你遇到困难,你可以将 [Github 上的完整示例代码](https://github.com/mdn/beginner-html-site-scripted/blob/main/scripts/main.js)与你的文件进行比较。 -![测试页面,添加了 一个 js 脚本,可以显示用户名、更改 Firefox 图片。](beginner-site-scripted.png) +我们才接触到 JavaScript 的表面。要是你玩得开心,并希望继续下去,好好利用下面的资源。 -若遇到问题,可以参考 GitHub 上的 [完整示例代码](https://github.com/roy-tian/learning-area/tree/master/extras/getting-started-web/beginner-html-site-scripted) 进行对比。 +## 参见 -本章介绍的 JavaScript 知识非常有限,更多内容请访问 [Javascript 学习页面](/zh-CN/docs/Learn/JavaScript)。 +- [JavaScript——动态客户端脚本语言](/zh-CN/docs/Learn/JavaScript) + - : 更深入地了解 JavaScript。 +- [学习 JavaScript](https://learnjavascript.online/) + - : 为有进取心的 Web 开发人员准备的优秀资源——在交互式环境中通过自动评估引导的短课程和交互式测试学习 JavaScript。前 40 节课为免费课程,而完整的课程仅需一次性支付少量费用。 {{PreviousMenuNext("Learn/Getting_started_with_the_web/CSS_basics", "Learn/Getting_started_with_the_web/Publishing_your_website", "Learn/Getting_started_with_the_web")}}