mirror of
https://github.com/apachecn/eloquent-js-3e-zh.git
synced 2025-05-23 11:52:20 +00:00
18
This commit is contained in:
parent
50f6978d6b
commit
c23122f2e5
176
18.md
176
18.md
@ -1,10 +1,22 @@
|
|||||||
## 十八、HTTP 和表单
|
## 十八、HTTP 和表单
|
||||||
|
|
||||||
|
> 原文:[HTTP and Forms](http://eloquentjavascript.net/18_http.html)
|
||||||
|
>
|
||||||
|
> 译者:[飞龙](https://github.com/wizardforcel)
|
||||||
|
>
|
||||||
|
> 协议:[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/)
|
||||||
|
>
|
||||||
|
> 自豪地采用[谷歌翻译](https://translate.google.cn/)
|
||||||
|
>
|
||||||
|
> 部分参考了[《JavaScript 编程精解(第 2 版)》](https://book.douban.com/subject/26707144/)
|
||||||
|
|
||||||
> 通信在实质上必须是无状态的,从客户端到服务器的每个请求都必须包含理解请求所需的所有信息,并且不能利用服务器上存储的任何上下文。
|
> 通信在实质上必须是无状态的,从客户端到服务器的每个请求都必须包含理解请求所需的所有信息,并且不能利用服务器上存储的任何上下文。
|
||||||
>
|
>
|
||||||
> Roy Fielding,《Architectural Styles and the Design of Network-based Software Architectures》
|
> Roy Fielding,《Architectural Styles and the Design of Network-based Software Architectures》
|
||||||
|
|
||||||
我们曾在第 13 章中提到过超文本传输协议(HTTP),万维网中通过该协议进行数据请求和传输。在本章中会对该协议进行详细介绍,并解释浏览器中JavaScript访问HTTP的方式。
|

|
||||||
|
|
||||||
|
我们曾在第 13 章中提到过超文本传输协议(HTTP),万维网中通过该协议进行数据请求和传输。在本章中会对该协议进行详细介绍,并解释浏览器中 JavaScript 访问 HTTP 的方式。
|
||||||
|
|
||||||
## 协议
|
## 协议
|
||||||
|
|
||||||
@ -36,23 +48,23 @@ Last-Modified: Mon, 08 Jan 2018 10:29:45 GMT
|
|||||||
GET /17_http.html HTTP/1.1
|
GET /17_http.html HTTP/1.1
|
||||||
```
|
```
|
||||||
|
|
||||||
请求中的第一个单词是请求方法。GET表示我们希望得到一个我们指定的资源。其他常用方式还有DELETE,用于删除一个资源;PUT用于替换资源;POST用于发送消息。需要注意的是服务器并不需要处理所有收到的请求。如果你随机访问一个网站并请求删除主页,服务器很有可能会拒绝你的请求。
|
请求中的第一个单词是请求方法。`GET`表示我们希望得到一个我们指定的资源。其他常用方式还有`DELETE`,用于删除一个资源;`PUT`用于替换资源;`POST`用于发送消息。需要注意的是服务器并不需要处理所有收到的请求。如果你随机访问一个网站并请求删除主页,服务器很有可能会拒绝你的请求。
|
||||||
|
|
||||||
方法名后的请求部分是所请求的资源的路径。在最简单的情况下,一个资源只是服务器中的一个文件。不过,协议并没有要求资源一定是实际文件。一个资源可以是任何可以像文件一样传输的东西。很多服务器会实时地生成这些资源。例如,如果你打开`github.com/marijnh`,服务器会在数据库中寻找名为`marijnjh`的用户,如果找到了则会为该用户的生成介绍页面。
|
方法名后的请求部分是所请求的资源的路径。在最简单的情况下,一个资源只是服务器中的一个文件。不过,协议并没有要求资源一定是实际文件。一个资源可以是任何可以像文件一样传输的东西。很多服务器会实时地生成这些资源。例如,如果你打开`github.com/marijnh`,服务器会在数据库中寻找名为`marijnjh`的用户,如果找到了则会为该用户的生成介绍页面。
|
||||||
|
|
||||||
请求的第一行中位于资源路径后面的HTTP/1.1用来表明所使用的HTTP协议的版本。
|
请求的第一行中位于资源路径后面的`HTTP/1.1`用来表明所使用的 HTTP 协议的版本。
|
||||||
|
|
||||||
在实践中,许多网站使用 HTTP v2,它支持与版本 1.1 相同的概念,但是要复杂得多,因此速度更快。 浏览器在与给定服务器通信时,会自动切换到适当的协议版本,并且无论使用哪个版本,请求的结果都是相同的。 由于 1.1 版更直接,更易于使用,因此我们将专注于此。
|
在实践中,许多网站使用 HTTP v2,它支持与版本 1.1 相同的概念,但是要复杂得多,因此速度更快。 浏览器在与给定服务器通信时,会自动切换到适当的协议版本,并且无论使用哪个版本,请求的结果都是相同的。 由于 1.1 版更直接,更易于使用,因此我们将专注于此。
|
||||||
|
|
||||||
服务器的响应也是以版本号开始的。版本号后面是应答状态,首先是一个三位的状态码,然后是一个可读的字符串。
|
服务器的响应也是以版本号开始的。版本号后面是响应状态,首先是一个三位的状态码,然后是一个可读的字符串。
|
||||||
|
|
||||||
```http
|
```http
|
||||||
HTTP/1.1 200 OK
|
HTTP/1.1 200 OK
|
||||||
```
|
```
|
||||||
|
|
||||||
以2开头的状态码表示请求成功。以4开头的状态码表示请求中有错误。404是最著名的HTTP状态码了,表示找不到资源。以5开头的状态码表示服务器端出现了问题,而请求没有问题。
|
以 2 开头的状态码表示请求成功。以 4 开头的状态码表示请求中有错误。404 是最著名的 HTTP 状态码了,表示找不到资源。以 5 开头的状态码表示服务器端出现了问题,而请求没有问题。
|
||||||
|
|
||||||
请求或响应的第一行后可能会有任意个协议头,多个形如“name:value”的行表明了和请求或响应相关的更多信息。这些是示例响应中的头信息。
|
请求或响应的第一行后可能会有任意个协议头,多个形如`name: value`的行表明了和请求或响应相关的更多信息。这些是示例响应中的头信息。
|
||||||
|
|
||||||
```http
|
```http
|
||||||
Content-Length: 65585
|
Content-Length: 65585
|
||||||
@ -60,17 +72,17 @@ Content-Type: text/html
|
|||||||
Last-Modified: Thu, 04 Jan 2018 14:05:30 GMT
|
Last-Modified: Thu, 04 Jan 2018 14:05:30 GMT
|
||||||
```
|
```
|
||||||
|
|
||||||
这些信息说明了响应文档的大小和类型。在这个例子中,响应是一个65585字节的HTML文档,同时也说明了该文档最后的更改时间。
|
这些信息说明了响应文档的大小和类型。在这个例子中,响应是一个 65585 字节的 HTML 文档,同时也说明了该文档最后的更改时间。
|
||||||
|
|
||||||
多数大多数协议头,客户端或服务器可以自由决定需要在请求或响应中包含的协议头,不过也有一些协议头是必需的。例如,指明主机名的Host头在请求中是必须的,因为一个服务器可能在一个IP地址下有多个主机名服务,如果没有Host头,服务器则无法判断客户端尝试请求哪个主机。
|
多数大多数协议头,客户端或服务器可以自由决定需要在请求或响应中包含的协议头,不过也有一些协议头是必需的。例如,指明主机名的`Host`头在请求中是必须的,因为一个服务器可能在一个 IP 地址下有多个主机名服务,如果没有`Host`头,服务器则无法判断客户端尝试请求哪个主机。
|
||||||
|
|
||||||
请求和应答可能都会在协议头后包含一个空行,后面则是消息体,包含所发送的数据。GET和DELETE请求不单独发送任何数据,但PUT和POST请求则会。同样地,一些响应类型(如错误应答)不需要有消息体。
|
请求和响应可能都会在协议头后包含一个空行,后面则是消息体,包含所发送的数据。`GET`和`DELETE`请求不单独发送任何数据,但`PUT`和`POST`请求则会。同样地,一些响应类型(如错误响应)不需要有消息体。
|
||||||
|
|
||||||
## 浏览器和 HTTP
|
## 浏览器和 HTTP
|
||||||
|
|
||||||
正如上例所示,当我们在浏览器地址栏输入一个URL后浏览器会发送一个请求。当HTML页面中包含有其他的文件,例如图片和JavaScript文件时,浏览器也会一并获取这些资源。
|
正如上例所示,当我们在浏览器地址栏输入一个 URL 后浏览器会发送一个请求。当 HTML 页面中包含有其他的文件,例如图片和 JavaScript 文件时,浏览器也会一并获取这些资源。
|
||||||
|
|
||||||
一个较为复杂的网站通常都会有10到200个不等的资源。为了可以很快地取得这些资源,浏览器会同时发送多个`GET`请求,而不是一次等待一个请求。此类文档都是通过GET方法来获取的。
|
一个较为复杂的网站通常都会有 10 到 200 个不等的资源。为了可以很快地取得这些资源,浏览器会同时发送多个`GET`请求,而不是一次等待一个请求。此类文档都是通过`GET`方法来获取的。
|
||||||
|
|
||||||
HTML页面可能包含表单,用户可以在表单中填入一些信息然后由浏览器将其发送到服务器。如下是一个表单的例子。
|
HTML页面可能包含表单,用户可以在表单中填入一些信息然后由浏览器将其发送到服务器。如下是一个表单的例子。
|
||||||
|
|
||||||
@ -92,7 +104,7 @@ GET /example/message.html?name=Jean&message=Yes%3F HTTP/1.1
|
|||||||
|
|
||||||
问号表示路径的末尾和查询字符串的起始。后面是多个名称和值,这些名称和值分别对应`form`输入字段中的`name`属性和这些元素的内容。`&`字符用来分隔不同的名称对。
|
问号表示路径的末尾和查询字符串的起始。后面是多个名称和值,这些名称和值分别对应`form`输入字段中的`name`属性和这些元素的内容。`&`字符用来分隔不同的名称对。
|
||||||
|
|
||||||
在这个 URL 中,经过编码的消息实际原本是“Yes?”,只不过浏览器用奇怪的代码替换了问号。我们必须替换掉请求字符串中的一些字符。使用%3F替换的问号就是其中之一。这样看,似乎有一个不成文的规定,每种格式都会有自己的转义字符。这里的编码格式叫作URL编码,使用一个百分号和16进制的数字来对字符进行编码。在这个例子中,3F(十进制为63)是问号字符的编码。JavaScript提供了encodeURIComponent和decodeURIComponent函数来按照这种格式进行编码和解码。
|
在这个 URL 中,经过编码的消息实际原本是`"Yes?"`,只不过浏览器用奇怪的代码替换了问号。我们必须替换掉请求字符串中的一些字符。使用`%3F`替换的问号就是其中之一。这样看,似乎有一个不成文的规定,每种格式都会有自己的转义字符。这里的编码格式叫作 URL 编码,使用一个百分号和16进制的数字来对字符进行编码。在这个例子中,3F(十进制为 63)是问号字符的编码。JavaScript 提供了`encodeURIComponent`和`decodeURIComponent`函数来按照这种格式进行编码和解码。
|
||||||
|
|
||||||
```js
|
```js
|
||||||
console.log(encodeURIComponent("Yes?"));
|
console.log(encodeURIComponent("Yes?"));
|
||||||
@ -101,7 +113,7 @@ console.log(decodeURIComponent("Yes%3F"));
|
|||||||
// → Yes?
|
// → Yes?
|
||||||
```
|
```
|
||||||
|
|
||||||
如果我们将本例HTML表单中的method属性更改为POST,则浏览器会使用POST方法发送该表单,并将请求字符串放到请求体中,而不是添加到URL中。
|
如果我们将本例 HTML 表单中的`method`属性更改为`POST`,则浏览器会使用`POST`方法发送该表单,并将请求字符串放到请求正文中,而不是添加到 URL 中。
|
||||||
|
|
||||||
```http
|
```http
|
||||||
POST /example/message.html HTTP/1.1
|
POST /example/message.html HTTP/1.1
|
||||||
@ -118,7 +130,7 @@ name=Jean&message=Yes%3F
|
|||||||
|
|
||||||
## Fetch
|
## Fetch
|
||||||
|
|
||||||
浏览器 JavaScript 可以通过`Fetch`接口生成 HTTP 请求。 由于它比较新,所以它很方便地使用了`Promise`(这在浏览器接口中很少见)。
|
浏览器 JavaScript 可以通过`fetch`接口生成 HTTP 请求。 由于它比较新,所以它很方便地使用了`Promise`(这在浏览器接口中很少见)。
|
||||||
|
|
||||||
```js
|
```js
|
||||||
fetch("example/data.txt").then(response => {
|
fetch("example/data.txt").then(response => {
|
||||||
@ -166,7 +178,7 @@ fetch("example/data.txt", {headers: {Range: "bytes=8-19"}})
|
|||||||
// → the content
|
// → the content
|
||||||
```
|
```
|
||||||
|
|
||||||
览器将自动添加一些请求头,例如`"Host"`和服务器需要的协议头,来确定正文的大小。 但是对于包含认证信息或告诉服务器想要接收的文件格式,添加自己的协议头通常很有用。
|
浏览器将自动添加一些请求头,例如`Host`和服务器需要的协议头,来确定正文的大小。 但是对于包含认证信息或告诉服务器想要接收的文件格式,添加自己的协议头通常很有用。
|
||||||
|
|
||||||
## HTTP 沙箱
|
## HTTP 沙箱
|
||||||
|
|
||||||
@ -182,25 +194,25 @@ Access-Control-Allow-Origin: *
|
|||||||
|
|
||||||
## 运用 HTTP
|
## 运用 HTTP
|
||||||
|
|
||||||
当构建一个需要让浏览器(客户端)的JavaScript程序和服务器端的程序进行通信的系统时,有一些不同的方式可以实现这个功能。
|
当构建一个需要让浏览器(客户端)的 JavaScript 程序和服务器端的程序进行通信的系统时,有一些不同的方式可以实现这个功能。
|
||||||
|
|
||||||
一个常用的方法是远程过程调用,通信遵从正常的方法调用方式,不过调用的方法实际运行在另一台机器中。调用包括向服务器发送包含方法名和参数的请求。响应的结果则包括函数的返回值。
|
一个常用的方法是远程过程调用,通信遵从正常的方法调用方式,不过调用的方法实际运行在另一台机器中。调用包括向服务器发送包含方法名和参数的请求。响应的结果则包括函数的返回值。
|
||||||
|
|
||||||
当考虑远程过程调用时,HTTP只是通信的载体,并且你很可能会写一个抽象层来隐藏细节。
|
当考虑远程过程调用时,HTTP 只是通信的载体,并且你很可能会写一个抽象层来隐藏细节。
|
||||||
|
|
||||||
另一个方法是使用一些资源和HTTP方法来建立自己的通信。不同于远程调用方法addUser,你需要发送一个PUT请求到/users/larry,不同于将用户属性进行编码后作为参数传递,你定义了一个 JSON 文档格式(或使用一种已有的格式)来展示一个用户。PUT请求的正文则只是这样的一个用来建立新资源的文档。由GET方法获取的资源则是自愿的URL(例如,/users/larry),该URL返回代表这个资源的文档。
|
另一个方法是使用一些资源和 HTTP 方法来建立自己的通信。不同于远程调用方法`addUser`,你需要发送一个`PUT`请求到`users/larry`,不同于将用户属性进行编码后作为参数传递,你定义了一个 JSON 文档格式(或使用一种已有的格式)来展示一个用户。`PUT`请求的正文则只是这样的一个用来建立新资源的文档。由`GET`方法获取的资源则是自愿的 URL(例如,`/users/larry`),该 URL 返回代表这个资源的文档。
|
||||||
|
|
||||||
第二种方法使用了HTTP的一些特性,所以使得整体更简洁。例如对于资源缓存的支持(在客户端存一份副本用于快速访问)。HTTP中使用的概念设计良好,可以提供一组有用的原则来设计服务器接口。
|
第二种方法使用了 HTTP 的一些特性,所以使得整体更简洁。例如对于资源缓存的支持(在客户端存一份副本用于快速访问)。HTTP 中使用的概念设计良好,可以提供一组有用的原则来设计服务器接口。
|
||||||
|
|
||||||
## 安全和 HTTPS
|
## 安全和 HTTPS
|
||||||
|
|
||||||
通过互联网传播的数据,往往走过漫长而危险的道路。 为了到达目的地,它必须跳过任何东西,从咖啡店的 Wi-Fi 到由各个公司和国家管理的网络。 在它的路线上的任何位置,它都可能被探测或者甚至被修改。
|
通过互联网传播的数据,往往走过漫长而危险的道路。 为了到达目的地,它必须跳过任何东西,从咖啡店的 Wi-Fi 到由各个公司和国家管理的网络。 在它的路线上的任何位置,它都可能被探测或者甚至被修改。
|
||||||
|
|
||||||
如果对某件事保密是重要的,例如您的电子邮件帐户的密码,或者它到达目的地而未经修改是重要的,例如帐户号码,您使用它在银行网站上转账,纯 HTTP 就不够好了。
|
如果对某件事保密是重要的,例如你的电子邮件帐户的密码,或者它到达目的地而未经修改是重要的,例如帐户号码,你使用它在银行网站上转账,纯 HTTP 就不够好了。
|
||||||
|
|
||||||
安全的 HTTP 协议,其 URL 以`https://`开头,是一种难以阅读和篡改的,HTTP 流量的封装方式。 在交换数据之前,客户端证实该服务器是它所声称的东西,通过要求它证明,它具有由浏览器承认的证书机构所颁发的证书。 接下来,通过连接传输的所有数据,都将以某种方式加密,它应该防止窃听和篡改。
|
安全的 HTTP 协议,其 URL 以`https://`开头,是一种难以阅读和篡改的,HTTP 流量的封装方式。 在交换数据之前,客户端证实该服务器是它所声称的东西,通过要求它证明,它具有由浏览器承认的证书机构所颁发的证书。 接下来,通过连接传输的所有数据,都将以某种方式加密,它应该防止窃听和篡改。
|
||||||
|
|
||||||
因此,当 HTTPS 正常工作时,它可以阻止某人冒充您想要与之通话的网站,以及某人窥探您的通信。 这并不完美,由于伪造或被盗的证书和损坏的软件,存在各种 HTTPS 失败的事故,但它比纯 HTTP 更安全。
|
因此,当 HTTPS 正常工作时,它可以阻止某人冒充你想要与之通话的网站,以及某人窥探你的通信。 这并不完美,由于伪造或被盗的证书和损坏的软件,存在各种 HTTPS 失败的事故,但它比纯 HTTP 更安全。
|
||||||
|
|
||||||
## 表单字段
|
## 表单字段
|
||||||
|
|
||||||
@ -208,21 +220,21 @@ Access-Control-Allow-Origin: *
|
|||||||
|
|
||||||
但是它们的元素是 DOM 的一部分,就像页面的其他部分一样,并且表示表单字段的 DOM 元素,支持许多其他元素上不存在的属性和事件。 这些使其可以使用 JavaScript 程序检查和控制这些输入字段,以及可以执行一些操作,例如向表单添加新功能,或在 JavaScript 应用程序中使用表单和字段作为积木。
|
但是它们的元素是 DOM 的一部分,就像页面的其他部分一样,并且表示表单字段的 DOM 元素,支持许多其他元素上不存在的属性和事件。 这些使其可以使用 JavaScript 程序检查和控制这些输入字段,以及可以执行一些操作,例如向表单添加新功能,或在 JavaScript 应用程序中使用表单和字段作为积木。
|
||||||
|
|
||||||
一个网页表单在其<form>标签中包含若干个输入字段。HTML允许多个的不同风格的输入字段,从简单的开/关选择框到下拉菜单和进行输入的字段。本书不会全面的讨论每一个输入字段类型,不过我们会先大概讲述一下。
|
一个网页表单在其`<form>`标签中包含若干个输入字段。HTML 允许多个的不同风格的输入字段,从简单的开关选择框到下拉菜单和进行输入的字段。本书不会全面的讨论每一个输入字段类型,不过我们会先大概讲述一下。
|
||||||
|
|
||||||
很多字段类型都使用<input>标签。标签的type属性用来选择字段的种类,下面是一些常用的<input>类型。
|
很多字段类型都使用`<input>`标签。标签的`type`属性用来选择字段的种类,下面是一些常用的`<input>`类型。
|
||||||
|
|
||||||
+ text:一个单行的文本输入框。
|
+ `text`:一个单行的文本输入框。
|
||||||
|
|
||||||
+ password:和text相同但隐藏了输入内容。
|
+ `password`:和`text`相同但隐藏了输入内容。
|
||||||
|
|
||||||
+ checkbox:一个复选框。
|
+ `checkbox`:一个复选框。
|
||||||
|
|
||||||
+ radio一个多选择字段中的一个单选框。
|
+ `radio`:一个多选择字段中的一个单选框。
|
||||||
|
|
||||||
+ file:允许用户从本机选择文件上传。
|
+ `file`:允许用户从本机选择文件上传。
|
||||||
|
|
||||||
表单字段并不一定要出现在<form>标签中。你可以把表单字段放置在一个页面的任何地方。但这样不带表单的字段不能被提交(一个完整的表单才可以),当需要和JavaScript进行响应时,我们通常也不希望按常规的方式提交表单。
|
表单字段并不一定要出现在`<form>`标签中。你可以把表单字段放置在一个页面的任何地方。但这样不带表单的字段不能被提交(一个完整的表单才可以),当需要和 JavaScript 进行响应时,我们通常也不希望按常规的方式提交表单。
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<p><input type="text" value="abc"> (text)</p>
|
<p><input type="text" value="abc"> (text)</p>
|
||||||
@ -236,7 +248,7 @@ Access-Control-Allow-Origin: *
|
|||||||
|
|
||||||
这些元素的 JavaScript 接口和元素类型不同。
|
这些元素的 JavaScript 接口和元素类型不同。
|
||||||
|
|
||||||
多行文本输入框有其自己的标签<textarea>,这样做是因为通过一个属性来声明一个多行初始值会十分奇怪。<textarea>要求有一个相匹配的</textarea>结束标签并使用标签之间的文本作为初始值,而不是使用value属性存储文本。
|
多行文本输入框有其自己的标签`<textarea>`,这样做是因为通过一个属性来声明一个多行初始值会十分奇怪。`<textarea>`要求有一个相匹配的`</textarea>`结束标签并使用标签之间的文本作为初始值,而不是使用`value`属性存储文本。
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<textarea>
|
<textarea>
|
||||||
@ -246,7 +258,7 @@ three
|
|||||||
</textarea>
|
</textarea>
|
||||||
```
|
```
|
||||||
|
|
||||||
<select>标签用来创造一个可以让用户从一些提前设定好的选项中进行选择的字段。
|
`<select>`标签用来创造一个可以让用户从一些提前设定好的选项中进行选择的字段。
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<select>
|
<select>
|
||||||
@ -256,15 +268,15 @@ three
|
|||||||
</select>
|
</select>
|
||||||
```
|
```
|
||||||
|
|
||||||
当一个表单字段中的内容更改时会触发change事件。
|
当一个表单字段中的内容更改时会触发`change`事件。
|
||||||
|
|
||||||
## 聚焦
|
## 聚焦
|
||||||
|
|
||||||
不同于HTML文档中的其他元素,表单字段可以获取键盘焦点。当点击或以某种方式激活时,他们会成为激活的元素,并接受键盘的输入。
|
不同于 HTML 文档中的其他元素,表单字段可以获取键盘焦点。当点击或以某种方式激活时,他们会成为激活的元素,并接受键盘的输入。
|
||||||
|
|
||||||
因此,只有获得焦点时,你才能输入文本字段。 其他字段对键盘事件的响应不同。 例如,`<select>`菜单尝试移动到包含用户输入文本的选项,并通过向上和向下移动其选项来响应箭头键。
|
因此,只有获得焦点时,你才能输入文本字段。 其他字段对键盘事件的响应不同。 例如,`<select>`菜单尝试移动到包含用户输入文本的选项,并通过向上和向下移动其选项来响应箭头键。
|
||||||
|
|
||||||
我们可以通过使用JavaScript的focus和blur方法来控制聚焦。第一个会聚焦到某一个DOM元素,第二个则使其失焦。在document.activeElement中的值会关联到当前聚焦的元素。
|
我们可以通过使用 JavaScript 的`focus`和`blur`方法来控制聚焦。第一个会聚焦到某一个 DOM 元素,第二个则使其失焦。在`document.activeElement`中的值会关联到当前聚焦的元素。
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<input type="text">
|
<input type="text">
|
||||||
@ -278,35 +290,35 @@ three
|
|||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
|
|
||||||
对于一些页面,用户希望立刻使用到一个表单字段。JavaScript可以在页面载入完成时将焦点放到这些字段上,HTML提供了autofocus属性,可以实现相同的效果,并让浏览器知道我们正在尝试实现的事情。这向浏览器提供了选项,来禁用一些错误的操作,例如用户希望将焦点置于其他地方。
|
对于一些页面,用户希望立刻使用到一个表单字段。JavaScript 可以在页面载入完成时将焦点放到这些字段上,HTML 提供了`autofocus`属性,可以实现相同的效果,并让浏览器知道我们正在尝试实现的事情。这向浏览器提供了选项,来禁用一些错误的操作,例如用户希望将焦点置于其他地方。
|
||||||
|
|
||||||
浏览器也允许用户通过TAB键来切换焦点。通过tabindex属性可以改变元素接受焦点的顺序。后面的例子会让焦点从文本输入框之间跳转到OK按钮而不是到帮助链接。
|
浏览器也允许用户通过 TAB 键来切换焦点。通过`tabindex`属性可以改变元素接受焦点的顺序。后面的例子会让焦点从文本输入框跳转到 OK 按钮而不是到帮助链接。
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<input type="text" tabindex=1> <a href=".">(help)</a>
|
<input type="text" tabindex=1> <a href=".">(help)</a>
|
||||||
<button onclick="console.log('ok')" tabindex=2>OK</button>
|
<button onclick="console.log('ok')" tabindex=2>OK</button>
|
||||||
```
|
```
|
||||||
|
|
||||||
默认情况下,多数的HTML元素不能被聚焦。但是可以通过添加tabindex属性使任何元素可聚焦。`tabindex`为 -1 使 TAB 键跳过元素,即使它通常是可聚焦的。
|
默认情况下,多数的 HTML 元素不能拥有焦点。但是可以通过添加`tabindex`属性使任何元素可聚焦。`tabindex`为 -1 使 TAB 键跳过元素,即使它通常是可聚焦的。
|
||||||
|
|
||||||
## 禁用字段
|
## 禁用字段
|
||||||
|
|
||||||
所有的表单字段都可以通过其disable属性来禁用。它是一个可以被指定为没有值的属性 - 事实上它出现在所有禁用的元素中。
|
所有的表单字段都可以通过其`disable`属性来禁用。它是一个可以被指定为没有值的属性 - 事实上它出现在所有禁用的元素中。
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<button>I'm all right</button>
|
<button>I'm all right</button>
|
||||||
<button disabled>I'm out</button>
|
<button disabled>I'm out</button>
|
||||||
```
|
```
|
||||||
|
|
||||||
禁用的字段不能被聚焦或更改,浏览器使它们变成灰色。
|
禁用的字段不能拥有焦点或更改,浏览器使它们变成灰色。
|
||||||
|
|
||||||
当一个程序在处理一些由按键或其他控制方式出发的事件,并且这些事件可能要求和服务器的通信时,将元素禁用直到动作完成可能是一个很好的方法。按照这用方式,当用户失去耐心并且再次点击时,不会意外的重复这一动作。
|
当一个程序在处理一些由按键或其他控制方式出发的事件,并且这些事件可能要求和服务器的通信时,将元素禁用直到动作完成可能是一个很好的方法。按照这用方式,当用户失去耐心并且再次点击时,不会意外的重复这一动作。
|
||||||
|
|
||||||
## 作为整体的表单
|
## 作为整体的表单
|
||||||
|
|
||||||
当一个字段被包含在<form>元素中时,其DOM元素会有一个form属性指向form的DOM元素。<form>元素则会有一个叫作elements属性,包含一个类似于数据的集合,其中包含全部的字段。
|
当一个字段被包含在`<form>`元素中时,其 DOM 元素会有一个`form`属性指向`form`的 DOM 元素。`<form>`元素则会有一个叫作`elements`属性,包含一个类似于数据的集合,其中包含全部的字段。
|
||||||
|
|
||||||
一个表单字段的name属性会决定在form提交时其内容的辨别方式。同时在获取form的elements属性时也可以作为一种属性名,所以elements属性既可以像数组(由编号来访问)一样使用也可以像映射一样访问(通过名字访问)。
|
一个表单字段的`name`属性会决定在`form`提交时其内容的辨别方式。同时在获取`form`的`elements`属性时也可以作为一种属性名,所以`elements`属性既可以像数组(由编号来访问)一样使用也可以像映射一样访问(通过名字访问)。
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<form action="example/submit.html">
|
<form action="example/submit.html">
|
||||||
@ -325,9 +337,9 @@ three
|
|||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
|
|
||||||
一个type属性为submit的按钮在点击时,会提交表单。在一个form被聚焦时,点击enter键也会有同样的效果。
|
`type`属性为`submit`的按钮在点击时,会提交表单。在一个`form`拥有焦点时,点击`enter`键也会有同样的效果。
|
||||||
|
|
||||||
通常在提交一个表单时,浏览器会将页面导航到form的action属性指明的页面,使用GET或POST请求。但是在这些发生之前,“submit”事件会被触发。这个事件可以由JavaScript处理,并且处理函数可以通过调用事件对象的preventDefault来禁用默认行为。
|
通常在提交一个表单时,浏览器会将页面导航到`form`的`action`属性指明的页面,使用`GET`或`POST`请求。但是在这些发生之前,`"submit"`事件会被触发。这个事件可以由 JavaScript 处理,并且处理器可以通过调用事件对象的`preventDefault`来禁用默认行为。
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<form action="example/submit.html">
|
<form action="example/submit.html">
|
||||||
@ -343,17 +355,17 @@ three
|
|||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
|
|
||||||
在JavaScript中submit事件有多种用途。我们可以编写代码来检测用户输入是否正确并且立刻提示错误信息,而不是提交表单。或者我们可以禁用正常的提交方式,正如这个例子中,让我们的程序处理输入,可能使用`fetch`将其发送到服务器而不重新加载页面。
|
在 JavaScript 中`submit`事件有多种用途。我们可以编写代码来检测用户输入是否正确并且立刻提示错误信息,而不是提交表单。或者我们可以禁用正常的提交方式,正如这个例子中,让我们的程序处理输入,可能使用`fetch`将其发送到服务器而不重新加载页面。
|
||||||
|
|
||||||
## 文本字段
|
## 文本字段
|
||||||
|
|
||||||
由type属性为text或password的<input>标签和textarea标签组成的字段有相同的接口。其DOM元素都有一个value属性,保存了为字符串格式的当前内容。将这个属性更改为另一个值将改变字段的内容。
|
由`type`属性为`text`或`password`的`<input>`标签和`textarea`标签组成的字段有相同的接口。其 DOM 元素都有一个`value`属性,保存了为字符串格式的当前内容。将这个属性更改为另一个值将改变字段的内容。
|
||||||
|
|
||||||
文本字段selectionStart和selectEnd属性包含光标和所选文字的信息。当没有选中文字时,这两个属性的值相同,表明当前光标的信息。例如,0表示文本的开始,10表示光标在第十个字符之后。当一部分字段被选中时,这两个属性值会不同,表明选中文字开始位置和结束位置。
|
文本字段`selectionStart`和`selectEnd`属性包含光标和所选文字的信息。当没有选中文字时,这两个属性的值相同,表明当前光标的信息。例如,0 表示文本的开始,10 表示光标在第十个字符之后。当一部分字段被选中时,这两个属性值会不同,表明选中文字开始位置和结束位置。
|
||||||
|
|
||||||
和正常的值一样,这些属性也可以被更改。
|
和正常的值一样,这些属性也可以被更改。
|
||||||
|
|
||||||
想象你正在编写关于Knaseknemwy的文章,但是名字拼写有一些问题,后续代码将<textarea>标签和一个事件处理器关联起来,当点击F2时,插入Knaseknemwy。
|
想象你正在编写关于 Knaseknemwy 的文章,但是名字拼写有一些问题,后续代码将`<textarea>`标签和一个事件处理器关联起来,当点击`F2`时,插入 Knaseknemwy。
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<textarea></textarea>
|
<textarea></textarea>
|
||||||
@ -377,7 +389,7 @@ three
|
|||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
|
|
||||||
replaceSelection函数用给定的字符串替换当前选中的文本字段内容,并将光标移动到替换内容后让用户可以继续输入。Change事件不会在每次有输入时都被调用,而是在内容在改变并失焦后触发。为了及时的响应文本字段的改变,则需要为input事件注册一个处理函数,每当用户有输入或更改时就被触发。
|
`replaceSelection`函数用给定的字符串替换当前选中的文本字段内容,并将光标移动到替换内容后让用户可以继续输入。`change`事件不会在每次有输入时都被调用,而是在内容在改变并失焦后触发。为了及时的响应文本字段的改变,则需要为`input`事件注册一个处理器,每当用户有输入或更改时就被触发。
|
||||||
|
|
||||||
下面的例子展示一个文本字段和一个展示字段中的文字的当前长度的计数器。
|
下面的例子展示一个文本字段和一个展示字段中的文字的当前长度的计数器。
|
||||||
|
|
||||||
@ -394,7 +406,7 @@ replaceSelection函数用给定的字符串替换当前选中的文本字段内
|
|||||||
|
|
||||||
## 选择框和单选框
|
## 选择框和单选框
|
||||||
|
|
||||||
一个选择框只是一个双选切换。其值可以通过其包含一个布尔值的checked属性来获取和更改。
|
一个选择框只是一个双选切换。其值可以通过其包含一个布尔值的`checked`属性来获取和更改。
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<label>
|
<label>
|
||||||
@ -409,9 +421,9 @@ replaceSelection函数用给定的字符串替换当前选中的文本字段内
|
|||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
|
|
||||||
<label>标签关联部分文本和一个输入字段。点击标签上的任何位置将激活该字段,这样会将其聚焦,并当它为复选框或单选按钮时切换它的值。
|
`<label>`标签关联部分文本和一个输入字段。点击标签上的任何位置将激活该字段,这样会将其聚焦,并当它为复选框或单选按钮时切换它的值。
|
||||||
|
|
||||||
单选框和选择框类似,不过单选框可以通过相同的name属性隐式的和其他几个单选框关联,保证只能选择其中一个。
|
单选框和选择框类似,不过单选框可以通过相同的`name`属性,隐式关联其他几个单选框,保证只能选择其中一个。
|
||||||
|
|
||||||
```html
|
```html
|
||||||
Color:
|
Color:
|
||||||
@ -440,13 +452,13 @@ Color:
|
|||||||
|
|
||||||
选择字段和单选按钮比较相似,允许用户从多个选项中选择。但是,单选框的展示排版是由我们控制的,而<select>标签外观则是由浏览器控制。
|
选择字段和单选按钮比较相似,允许用户从多个选项中选择。但是,单选框的展示排版是由我们控制的,而<select>标签外观则是由浏览器控制。
|
||||||
|
|
||||||
选择字段也有一个更类似于复选框列表的变体,而不是单选框。 当赋予`multiple`属性时,`<select>`标签将允许用户选择任意数量的选项,而不仅仅是一个选项。 在大多数浏览器中,这会显示与正常的选择字段不同的效果,后者通常显示为下拉控件,仅在您打开它时才显示选项。
|
选择字段也有一个更类似于复选框列表的变体,而不是单选框。 当赋予`multiple`属性时,`<select>`标签将允许用户选择任意数量的选项,而不仅仅是一个选项。 在大多数浏览器中,这会显示与正常的选择字段不同的效果,后者通常显示为下拉控件,仅在你打开它时才显示选项。
|
||||||
|
|
||||||
每一个<option>选项会有一个值,这个值可以通过value属性来定义。如果没有提供,选项内的文本将作为其值。<select>的value属性反映了当前的选中项。对于一个多选字段,这个属性用处不太大因为该属性只会给出一个选中项。
|
每一个`<option>`选项会有一个值,这个值可以通过`value`属性来定义。如果没有提供,选项内的文本将作为其值。`<select>`的`value`属性反映了当前的选中项。对于一个多选字段,这个属性用处不太大因为该属性只会给出一个选中项。
|
||||||
|
|
||||||
<select>字段的<option>标签可以通过一个类似于数组对象的options属性访问到。每个选项会有一个叫作selected的属性,来表明这个选项当前是否被选中。这个属性可以用来被设定选中或不选中。
|
`<select>`字段的`<option>`标签可以通过一个类似于数组对象的`options`属性访问到。每个选项会有一个叫作`selected`的属性,来表明这个选项当前是否被选中。这个属性可以用来被设定选中或不选中。
|
||||||
|
|
||||||
这个例子会从多选字段中取出选中的数值,并使用这些数值构造一个二进制数字。按住CTRL(或Mac的COMMAND键)来选择多个选项。
|
这个例子会从多选字段中取出选中的数值,并使用这些数值构造一个二进制数字。按住`CTRL`(或 Mac 的`COMMAND`键)来选择多个选项。
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<select multiple>
|
<select multiple>
|
||||||
@ -472,7 +484,7 @@ Color:
|
|||||||
|
|
||||||
## 文件字段
|
## 文件字段
|
||||||
|
|
||||||
文件字段最初是用于通过表单来上传从浏览器机器中获取的文件。在现代浏览器中,也可以从JavaScript程序中读取文件。该字段则作为一个看门人角色。脚本不能简单地直接从用户的电脑中读取文件,但是如果用户在这个字段中选择了一个文件,浏览器会将这个行为解释为脚本,便可以访问该文件。
|
文件字段最初是用于通过表单来上传从浏览器机器中获取的文件。在现代浏览器中,也可以从 JavaScript 程序中读取文件。该字段则作为一个看门人角色。脚本不能简单地直接从用户的电脑中读取文件,但是如果用户在这个字段中选择了一个文件,浏览器会将这个行为解释为脚本,便可以访问该文件。
|
||||||
|
|
||||||
一个文本字段是一个类似于“选择文件”或“浏览”标签的按钮,后面跟着所选文件的信息。
|
一个文本字段是一个类似于“选择文件”或“浏览”标签的按钮,后面跟着所选文件的信息。
|
||||||
|
|
||||||
@ -490,11 +502,11 @@ Color:
|
|||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
|
|
||||||
文本字段的files属性是一个类似数组的对象(当然,不是一个真正的数组),包含在字段中所选择的文件。开始时是空的。因此文本字段属性不仅仅是file属性。有时文本字段可以上传多个文件,这使得同时选择多个文件变为可能。
|
文本字段的`files`属性是一个类数组对象(当然,不是一个真正的数组),包含在字段中所选择的文件。开始时是空的。因此文本字段属性不仅仅是`file`属性。有时文本字段可以上传多个文件,这使得同时选择多个文件变为可能。
|
||||||
|
|
||||||
files对象中的对象有name(文件名)、size(文件大小,单位为字节),和type(文件的媒体类型,如text/plain,image/jped)等属性。
|
`files`对象中的对象有`name`(文件名)、`size`(文件大小,单位为字节),和`type`(文件的媒体类型,如`text/plain`,`image/jpeg`)等属性。
|
||||||
|
|
||||||
而files属性中不包含文件内容的属性。获取这个内容会比较复杂。由于从硬盘中读取文件会需要一些时间,接口必须是异步的,来避免文档的无响应问题。
|
而`files`属性中不包含文件内容的属性。获取这个内容会比较复杂。由于从硬盘中读取文件会需要一些时间,接口必须是异步的,来避免文档的无响应问题。
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<input type="file" multiple>
|
<input type="file" multiple>
|
||||||
@ -513,9 +525,9 @@ files对象中的对象有name(文件名)、size(文件大小,单位为
|
|||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
|
|
||||||
读取文件是通过FileReader对象实现的,注册一个load事件处理器,然后调用readAsText方法,传入我们希望读取的文件,一旦载入完成,reader的result属性内容就是文件内容。
|
读取文件是通过`FileReader`对象实现的,注册一个`load`事件处理器,然后调用`readAsText`方法,传入我们希望读取的文件,一旦载入完成,`reader`的`result`属性内容就是文件内容。
|
||||||
|
|
||||||
FileReader对象还会在读取文件失败时触发error事件。错误对象本身会存在reader的error属性中。这个接口是在`Promise`成为语言的一部分之前设计的。 你可以把它包装在`Promise`中,像这样:
|
`FileReader`对象还会在读取文件失败时触发`error`事件。错误对象本身会存在`reader`的`error`属性中。这个接口是在`Promise`成为语言的一部分之前设计的。 你可以把它包装在`Promise`中,像这样:
|
||||||
|
|
||||||
```html
|
```html
|
||||||
function readFileText(file) {
|
function readFileText(file) {
|
||||||
@ -533,9 +545,9 @@ function readFileText(file) {
|
|||||||
|
|
||||||
## 客户端保存数据
|
## 客户端保存数据
|
||||||
|
|
||||||
采用JavaScript代码的简单HTML页面可以作为实现一些小应用的很好的途径。可以采用小的帮助程序来自动化一些基本的任务。通过关联一些表单字段和事件处理函数,你可以实现华氏度与摄氏度的转换。也可以实现由主密码和网站名来生成密码等各种任务。
|
采用 JavaScript 代码的简单 HTML 页面可以作为实现一些小应用的很好的途径。可以采用小的帮助程序来自动化一些基本的任务。通过关联一些表单字段和事件处理器,你可以实现华氏度与摄氏度的转换。也可以实现由主密码和网站名来生成密码等各种任务。
|
||||||
|
|
||||||
当一个应用需要存储一些东西以便于跨对话使用时,则不能使用JavaScript绑定因为每当页面关闭时这些值就会丢失。你可以搭建一个服务器,连接到因特网,将一些服务数据存储到其中。在第20章中将会介绍如何实现这些,当然这需要很多的工作,也有一定的复杂度。有时只要将数据存储在浏览器中即可。
|
当一个应用需要存储一些东西以便于跨对话使用时,则不能使用 JavaScript 绑定因为每当页面关闭时这些值就会丢失。你可以搭建一个服务器,连接到因特网,将一些服务数据存储到其中。在第20章中将会介绍如何实现这些,当然这需要很多的工作,也有一定的复杂度。有时只要将数据存储在浏览器中即可。
|
||||||
|
|
||||||
`localStorage`对象可以用于保存数据,它在页面重新加载后还存在。这个对象允许你将字符串存储在某个名字(也是字符串)下,下面是具体示例。
|
`localStorage`对象可以用于保存数据,它在页面重新加载后还存在。这个对象允许你将字符串存储在某个名字(也是字符串)下,下面是具体示例。
|
||||||
|
|
||||||
@ -546,13 +558,13 @@ console.log(localStorage.getItem("username"));
|
|||||||
localStorage.removeItem("username");
|
localStorage.removeItem("username");
|
||||||
```
|
```
|
||||||
|
|
||||||
一个在localStorage中的值会保留到其被重写时,它也可以通过removeItem来清除,或者由用户清除本地数据。
|
一个在`localStorage`中的值会保留到其被重写时,它也可以通过`removeItem`来清除,或者由用户清除本地数据。
|
||||||
|
|
||||||
不同字段名的站点的数据会存在不同的地方。这也表明原则上由localStorage存储的数据只可以由相同站点的脚本编辑。
|
不同字段名的站点的数据会存在不同的地方。这也表明原则上由`localStorage`存储的数据只可以由相同站点的脚本编辑。
|
||||||
|
|
||||||
浏览器的确限制一个站点可以存储的localStorage的数据大小。这种限制,以及用垃圾填满人们的硬盘并不是真正有利可图的事实,防止该特性占用太多空间。
|
浏览器的确限制一个站点可以存储的`localStorage`的数据大小。这种限制,以及用垃圾填满人们的硬盘并不是真正有利可图的事实,防止该特性占用太多空间。
|
||||||
|
|
||||||
下面的代码实现了一个粗糙的笔记应用。程序将用户的笔记保存为一个对象,将笔记的标题和内容字符串相关联。对象被编码为JSON格式并存储在localStorage中。用户可以从<select>选择字段中选择笔记并在<textarea>中编辑笔记,并可以通过点击一个按钮来添加笔记。
|
下面的代码实现了一个粗糙的笔记应用。程序将用户的笔记保存为一个对象,将笔记的标题和内容字符串相关联。对象被编码为 JSON 格式并存储在`localStorage`中。用户可以从`<select>`选择字段中选择笔记并在`<textarea>`中编辑笔记,并可以通过点击一个按钮来添加笔记。
|
||||||
|
|
||||||
```html
|
```html
|
||||||
Notes: <select></select> <button>Add</button><br>
|
Notes: <select></select> <button>Add</button><br>
|
||||||
@ -604,13 +616,13 @@ Notes: <select></select> <button>Add</button><br>
|
|||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
|
|
||||||
脚本从存储在localStorage中的`"Notes"`值来获取它的初始状态,如果其中没有值,它会创建示例状态,仅仅带有一个购物列表。从localStorage中读取不存在的字段会返回null。
|
脚本从存储在`localStorage`中的`"Notes"`值来获取它的初始状态,如果其中没有值,它会创建示例状态,仅仅带有一个购物列表。从`localStorage`中读取不存在的字段会返回`null`。
|
||||||
|
|
||||||
`setState`方法确保 DOM 显示给定的状态,并将新状态存储到`localStorage`。 事件处理器调用这个函数来移动到一个新状态。
|
`setState`方法确保 DOM 显示给定的状态,并将新状态存储到`localStorage`。 事件处理器调用这个函数来移动到一个新状态。
|
||||||
|
|
||||||
在这个例子中使用`Object.assign`,是为了创建一个新的对象,它是旧的`state.notes`的一个克隆,但是添加或覆盖了一个属性。 `Object.assign`选取第一个参数,向其添加所有更多参数的所有属性。 因此,向它提供一个空对象会使它填充一个新对象。 第三个参数中的方括号表示法,用于创建名称基于某个动态值的属性。
|
在这个例子中使用`Object.assign`,是为了创建一个新的对象,它是旧的`state.notes`的一个克隆,但是添加或覆盖了一个属性。 `Object.assign`选取第一个参数,向其添加所有更多参数的所有属性。 因此,向它提供一个空对象会使它填充一个新对象。 第三个参数中的方括号表示法,用于创建名称基于某个动态值的属性。
|
||||||
|
|
||||||
还有另一个和localStorage很相似的对象叫作sessionStorage。这两个对象之间的区别在于sessionStorage的内容会在每次会话结束时丢失,而对于多数浏览器来说,会话会在浏览器关闭时结束。
|
还有另一个和`localStorage`很相似的对象叫作`sessionStorage`。这两个对象之间的区别在于`sessionStorage`的内容会在每次会话结束时丢失,而对于多数浏览器来说,会话会在浏览器关闭时结束。
|
||||||
|
|
||||||
## 本章小结
|
## 本章小结
|
||||||
|
|
||||||
@ -628,13 +640,13 @@ fetch("/18_http.html").then(r => r.text()).then(text => {
|
|||||||
|
|
||||||
HTML可以表示多种表单字段,例如文本字段、选择框、多选字段和文件选取。
|
HTML可以表示多种表单字段,例如文本字段、选择框、多选字段和文件选取。
|
||||||
|
|
||||||
这些字段可以用 JavaScript 进行控制和读取。内容改变时会触发change事件,文本有输入时会触发input事件,键盘获得焦点时触发键盘事件。 例如“value”(用于文本和选择字段)或“checked”(用于复选框和单选按钮)的属性,用于读取或设置字段的内容。
|
这些字段可以用 JavaScript 进行控制和读取。内容改变时会触发`change`事件,文本有输入时会触发`input`事件,键盘获得焦点时触发键盘事件。 例如`"value"`(用于文本和选择字段)或`"checked"`(用于复选框和单选按钮)的属性,用于读取或设置字段的内容。
|
||||||
|
|
||||||
当一个表单被提交时,会触发其submit事件,JavaScript处理器可以通过调用preventDefault来禁用默认的提交事件。表单字段的元素不一定需要被包装在<form>标签中。
|
当一个表单被提交时,会触发其`submit`事件,JavaScript 处理器可以通过调用`preventDefault`来禁用默认的提交事件。表单字段的元素不一定需要被包装在`<form>`标签中。
|
||||||
|
|
||||||
当用户在一个文件选择字段中选择了本机中的一个文件时,可以用FileReader接口来在JavaScript中获取文件内容。
|
当用户在一个文件选择字段中选择了本机中的一个文件时,可以用`FileReader`接口来在 JavaScript 中获取文件内容。
|
||||||
|
|
||||||
localStorage和sessionStorage对象可以用来保存页面重载后依旧保留的信息。第一个会永久保留数据(直到用户决定清楚),第二个则会保存到浏览器关闭时。
|
`localStorage`和`sessionStorage`对象可以用来保存页面重载后依旧保留的信息。第一个会永久保留数据(直到用户决定清除),第二个则会保存到浏览器关闭时。
|
||||||
|
|
||||||
## 习题
|
## 习题
|
||||||
|
|
||||||
@ -642,11 +654,11 @@ localStorage和sessionStorage对象可以用来保存页面重载后依旧保留
|
|||||||
|
|
||||||
HTTP 可以做的事情之一就是内容协商。 `Accept`请求头用于告诉服务器,客户端想要获得什么类型的文档。 许多服务器忽略这个协议头,但是当一个服务器知道各种编码资源的方式时,它可以查看这个协议头,并发送客户端首选的格式。
|
HTTP 可以做的事情之一就是内容协商。 `Accept`请求头用于告诉服务器,客户端想要获得什么类型的文档。 许多服务器忽略这个协议头,但是当一个服务器知道各种编码资源的方式时,它可以查看这个协议头,并发送客户端首选的格式。
|
||||||
|
|
||||||
URL `eloquentjavascript.net/author`配置为响应明文,HTML 或 JSON,具体取决于客户端要求的内容。 这些格式由标准化的媒体类型“text / plain”,“text / html”和“application / json”标识。
|
URL `eloquentjavascript.net/author`配置为响应明文,HTML 或 JSON,具体取决于客户端要求的内容。 这些格式由标准化的媒体类型`"text/plain"`,`"text/html"`和`"application/json"`标识。
|
||||||
|
|
||||||
发送请求来获取此资源的所有三种格式。 使用传递给`fetch`的`options`对象中的`headers`属性,将名为`Accept`的协议头设置为所需的媒体类型。
|
发送请求来获取此资源的所有三种格式。 使用传递给`fetch`的`options`对象中的`headers`属性,将名为`Accept`的协议头设置为所需的媒体类型。
|
||||||
|
|
||||||
最后,请尝试请求媒体类型“application/rainbows+unicorns”,并查看产生的状态码。
|
最后,请尝试请求媒体类型`"application/rainbows+unicorns"`,并查看产生的状态码。
|
||||||
|
|
||||||
```js
|
```js
|
||||||
// Your code here.
|
// Your code here.
|
||||||
@ -670,19 +682,19 @@ URL `eloquentjavascript.net/author`配置为响应明文,HTML 或 JSON,具
|
|||||||
|
|
||||||
### Conway 的生命游戏
|
### Conway 的生命游戏
|
||||||
|
|
||||||
Conway的生命游戏是一个简单的在方格中模拟生命的游戏,每一个小格都可以生存或灭亡。对于每一代生命都要遵循以下条件:
|
Conway 的生命游戏是一个简单的在网格中模拟生命的游戏,每一个细胞都可以生存或灭亡。对于每一代(回合),都要遵循以下规则:
|
||||||
|
|
||||||
+ 任何小格周围有少于两个或多于三个的活着的邻居都会死亡。
|
+ 任何细胞,周围有少于两个或多于三个的活着的邻居,都会死亡。
|
||||||
|
|
||||||
+ 任意两个或三个的活着的邻居的小格可以生存到下一代。
|
+ 任意细胞,拥有两个或三个的活着的邻居,可以生存到下一代。
|
||||||
|
|
||||||
+ 任何死去的、有三个活着的邻居的小格可以再次复活。
|
+ 任何死去的细胞,周围有三个活着的邻居,可以再次复活。
|
||||||
|
|
||||||
任意一个相连的小格都可以称为邻居,包括对角相连。
|
任意一个相连的细胞都可以称为邻居,包括对角相连。
|
||||||
|
|
||||||
注意这些规则要立刻应用于整个网格,而不是一次一个方格。这表明邻居的数目由开始的一代决定,并且邻居在每一代时发生的变化不应该影响给定小格新的状态。
|
注意这些规则要立刻应用于整个网格,而不是一次一个网格。这表明邻居的数目由开始的一代决定,并且邻居在每一代时发生的变化不应该影响给定细胞新的状态。
|
||||||
|
|
||||||
使用任何一个你认为合适的数据结构来实现这个游戏。使用Math.random来随机的生成开始状态。将其展示为一个选择框组成的网格和一个生成下一代的按钮。当用户选中或取消选中一个选择框时,其变化应该影响下一代的计算。
|
使用任何一个你认为合适的数据结构来实现这个游戏。使用`Math.random`来随机的生成开始状态。将其展示为一个选择框组成的网格和一个生成下一代的按钮。当用户选中或取消选中一个选择框时,其变化应该影响下一代的计算。
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<div id="grid"></div>
|
<div id="grid"></div>
|
||||||
|
BIN
img/18-0.jpg
Normal file
BIN
img/18-0.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 21 KiB |
Loading…
x
Reference in New Issue
Block a user