Skip to content

Commit e2277f1

Browse files
authored
Update some chapters to [Jul 17, 2020] Part-6 (#795)
* update some chacters * update some chacters
1 parent 99cd068 commit e2277f1

File tree

27 files changed

+533
-134
lines changed

27 files changed

+533
-134
lines changed

2-ui/1-document/01-browser-environment/article.md

+4-6
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
JavaScript 语言最初是为 Web 浏览器创建的。此后,它已经发展成为一种具有多种用途和平台的语言。
44

5-
平台可以是一个浏览器,一个 Web 服务器,或其他 **主机(host)**甚至是咖啡机。它们每个都提供了特定于平台的功能。JavaScript 规范将其称为 **主机环境**
5+
平台可以是一个浏览器,一个 Web 服务器,或其他 **主机(host)**甚至可以是一个“智能”咖啡机,如果它能运行 JavaScript 的话。它们每个都提供了特定于平台的功能。JavaScript 规范将其称为 **主机环境**
66

77
主机环境提供了自己的对象和语言核心以外的函数。Web 浏览器提供了一种控制网页的方法。Node.JS 提供了服务器端功能,等等。
88

@@ -49,9 +49,7 @@ document.body.style.background = "red";
4949
setTimeout(() => document.body.style.background = "", 1000);
5050
```
5151

52-
在这里,我们使用了 `document.body.style`,但还有很多很多其他的东西。规范中有属性和方法的详细描述:
53-
54-
- **DOM Living Standard**<https://dom.spec.whatwg.org>
52+
在这里,我们使用了 `document.body.style`,但还有很多很多其他的东西。规范中有属性和方法的详细描述:[DOM Living Standard](https://dom.spec.whatwg.org)
5553

5654
```smart header="DOM 不仅仅用于浏览器"
5755
DOM 规范解释了文档的结构,并提供了操作文档的对象。有的非浏览器设备也使用 DOM。
@@ -60,9 +58,9 @@ DOM 规范解释了文档的结构,并提供了操作文档的对象。有的
6058
```
6159

6260
```smart header="用于样式的 CSSOM"
63-
CSS 规则和样式表的结构与 HTML 不同。有一个单独的规范 [CSS Object Model (CSSOM)](https://www.w3.org/TR/cssom-1/),它解释了如何将 CSS 表示为对象,以及如何读写它们。
61+
There's also a separate specification, [CSS Object Model (CSSOM)](https://www.w3.org/TR/cssom-1/) for CSS rules and stylesheets, that explains how they are represented as objects, and how to read and write them.
6462
65-
当我们修改文档的样式规则时,CSSOM 与 DOM 是一起使用的。但实际上,很少需要 CSSOM,因为通常 CSS 规则是静态的。我们很少需要从 JavaScript 中添加/删除 CSS 规则,但你要知道这是可行的。
63+
当我们修改文档的样式规则时,CSSOM 与 DOM 是一起使用的。但实际上,很少需要 CSSOM,因为 we rarely need to modify CSS rules from JavaScript (usually we just add/remove CSS classes, not modify their CSS rules), but that's also possible.
6664
```
6765

6866
## 浏览器对象模型(BOM)

2-ui/1-document/07-modifying-document/article.md

+25-12
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ DOM 修改是创建“实时”页面的关键。
2828
*/!*
2929
```
3030

31-
这是一个 HTML 示例。现在,让我们使用 JavaScript 创建一个相同的 `div`假设样式在 HTML 或外部 CSS 文件中)。
31+
这是一个 HTML 示例。现在,让我们使用 JavaScript 创建一个相同的 `div`假设样式已经在 HTML/CSS 文件中)。
3232

3333
## 创建一个元素
3434

@@ -48,21 +48,28 @@ DOM 修改是创建“实时”页面的关键。
4848
let textNode = document.createTextNode('Here I am');
4949
```
5050

51+
Most of the time we need to create element nodes, such as the `div` for the message.
52+
5153
### 创建一条消息
5254

53-
在我们的例子中,消息是一个带有 `alert` 类和 HTML 的 `div`
55+
Creating the message div takes 3 steps:
5456

5557
```js
58+
// 1. Create <div> element
5659
let div = document.createElement('div');
60+
61+
// 2. Set its class to "alert"
5762
div.className = "alert";
63+
64+
// 3. Fill it with the content
5865
div.innerHTML = "<strong>Hi there!</strong> You've read an important message.";
5966
```
6067

61-
我们创建了元素,但到目前为止,它还只是在变量中。我们无法在页面上看到该元素,因为它还不是文档的一部分
68+
我们已经创建了该元素。但到目前为止,它还只是在一个名为 `div` 的变量中,尚未在页面中。所以我们无法在页面上看到它
6269

6370
## 插入方法
6471

65-
为了让 `div` 显示出来,我们需要将其插入到 `document` 中的某处。例如,`document.body` 中。
72+
为了让 `div` 显示出来,我们需要将其插入到 `document` 中的某处。例如,into `<body>` element, referenced by `document.body`.
6673

6774
对此有一个特殊的方法 `append``document.body.append(div)`
6875

@@ -90,14 +97,20 @@ div.innerHTML = "<strong>Hi there!</strong> You've read an important message.";
9097
</script>
9198
```
9299

93-
下面这些方法提供了更多的插入方式:
100+
Here we called `append` on `document.body`, but we can call `append` method on any other element, to put another element into it. For instance, we can append something to `<div>` by calling `div.append(anotherElement)`.
94101

95-
- `node.append(...nodes or strings)` — 在 `node` 末尾插入节点或字符串,
96-
- `node.prepend(...nodes or strings)` — 在 `node` 开头插入节点或字符串,
97-
- `node.before(...nodes or strings)` — 在 `node` 前面插入节点或字符串,
98-
- `node.after(...nodes or strings)` — 在 `node` 后面插入节点或字符串,
102+
Here are more insertion methods, they specify different places where to insert:
103+
104+
- `node.append(...nodes or strings)` — 在 `node` **末尾** 插入节点或字符串,
105+
- `node.prepend(...nodes or strings)` — 在 `node` **开头** 插入节点或字符串,
106+
- `node.before(...nodes or strings)` — 在 `node` **前面** 插入节点或字符串,
107+
- `node.after(...nodes or strings)` — 在 `node` **后面** 插入节点或字符串,
99108
- `node.replaceWith(...nodes or strings)` — 将 `node` 替换为给定的节点或字符串。
100109

110+
Arguments of these methods are an arbitrary list of DOM nodes to insert, or text strings (that become text nodes automatically).
111+
112+
Let's see them in action.
113+
101114
下面是使用这些方法将列表项添加到列表中,以及将文本添加到列表前面和后面的示例:
102115

103116
```html autorun
@@ -139,7 +152,7 @@ before
139152
after
140153
```
141154

142-
这些方法可以在单个调用中插入多个节点列表和文本片段。
155+
如上所述,这些方法可以在单个调用中插入多个节点列表和文本片段。
143156

144157
例如,在这里插入了一个字符串和一个元素:
145158

@@ -150,7 +163,7 @@ after
150163
</script>
151164
```
152165

153-
所有内容都被“作为文本”插入。
166+
Please note: the text is inserted "as text", not "as HTML", with proper escaping of characters such as `<`, `>`.
154167

155168
所以,最终的 HTML 为:
156169

@@ -166,7 +179,7 @@ after
166179

167180
所以,这些方法只能用来插入 DOM 节点或文本片段。
168181

169-
但是,如果我们想在所有标签和内容正常工作的情况下,将这些内容“作为 HTML” 插入到 HTML 中,就像 `elem.innerHTML` 方法一样,那有什么方法可以实现吗?
182+
But what if we'd like to insert an HTML string "as html", with all tags and stuff working, in the same manner as `elem.innerHTML` does it?
170183

171184
## insertAdjacentHTML/Text/Element
172185

2-ui/1-document/09-size-and-scroll/article.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ element.style.height = `${element.scrollHeight}px`;
211211
<div onclick="this.scrollTop+=10" style="cursor:pointer;border:1px solid black;width:100px;height:80px;overflow:auto">Click<br>Me<br>1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9</div>
212212
```
213213

214-
`scrollTop` 设置为 `0` `Infinity` 将会使元素滚动到顶部/底部。
214+
`scrollTop` 设置为 `0` 或一个大的值,例如 `1e9`将会使元素滚动到顶部/底部。
215215
````
216216
217217
## 不要从 CSS 中获取 width/height

2-ui/1-document/11-coordinates/article.md

+2
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,8 @@ function getCoords(elem) {
216216
217217
return {
218218
top: box.top + window.pageYOffset,
219+
right: box.right + window.pageXOffset,
220+
bottom: box.bottom + window.pageYOffset,
219221
left: box.left + window.pageXOffset
220222
};
221223
}

2-ui/2-events/01-introduction-browser-events/article.md

+37-38
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@
1111
- `mousedown` / `mouseup` —— 当在元素上按下/释放鼠标按钮时。
1212
- `mousemove` —— 当鼠标移动时。
1313

14+
**键盘事件**
15+
- `keydown` and `keyup` -- when a keyboard key is pressed and released.
16+
1417
**表单(form)元素事件**
1518
- `submit` —— 当访问者提交了一个 `<form>` 时。
1619
- `focus` —— 当访问者聚焦于一个元素时,例如聚焦于一个 `<input>`
1720

18-
**键盘事件**
19-
- `keydown``keyup` —— 当访问者按下然后松开按键时。
20-
2121
**Document 事件**
2222
- `DOMContentLoaded` —— 当 HTML 的加载和处理均完成,DOM 被完全构建完成时。
2323

@@ -87,8 +87,6 @@ HTML 特性不是编写大量代码的好位置,因此我们最好创建一个
8787

8888
因此,这种方法实际上与前一种方法相同。
8989

90-
**处理程序总是在 DOM 属性中:HTML 特性只是初始化它的方法之一**
91-
9290
这两段代码工作相同:
9391

9492
1. 只有 HTML:
@@ -109,6 +107,8 @@ HTML 特性不是编写大量代码的好位置,因此我们最好创建一个
109107
</script>
110108
```
111109

110+
In the first example, the HTML attribute is used to initialize the `button.onclick`, while in the second example -- the script, that's all the difference.
111+
112112
**因为这里只有一个 `onclick` 属性,所以我们无法分配更多事件处理程序。**
113113

114114
在下面这个示例中,我们使用 JavaScript 添加了一个处理程序,覆盖了现有的处理程序:
@@ -124,16 +124,6 @@ HTML 特性不是编写大量代码的好位置,因此我们最好创建一个
124124
</script>
125125
```
126126

127-
顺便说一下,我们可以直接将现有的函数指定为处理程序:
128-
129-
```js
130-
function sayThanks() {
131-
alert('Thanks!');
132-
}
133-
134-
elem.onclick = sayThanks;
135-
```
136-
137127
要移除一个处理程序 —— 赋值 `elem.onclick = null`
138128

139129
## 访问元素:this
@@ -150,7 +140,17 @@ elem.onclick = sayThanks;
150140

151141
如果你刚开始写事件 —— 请注意一些细微之处。
152142

153-
**函数应该被以 `sayThanks` 的形式进行非配,而不是 `sayThanks()`**
143+
We can set an existing function as a handler:
144+
145+
```js
146+
function sayThanks() {
147+
alert('Thanks!');
148+
}
149+
150+
elem.onclick = sayThanks;
151+
```
152+
153+
But be careful: the function should be assigned as `sayThanks`, not `sayThanks()`.
154154

155155
```js
156156
// 正确
@@ -160,29 +160,25 @@ button.onclick = sayThanks;
160160
button.onclick = sayThanks();
161161
```
162162

163-
如果我们添加了括号 `sayThanks()` —— 这是一个函数调用。所以,最后一行代码实际上获得的是函数执行的 **结果**,即 `undefined`(因为这个函数没有返回值)。此代码不会工作。
163+
如果我们添加了括号,那么 `sayThanks()` 就变成了一个函数调用。所以,最后一行代码实际上获得的是函数执行的 **结果**,即 `undefined`(因为这个函数没有返回值)。此代码不会工作。
164164

165165
……但在标记(markup)中,我们确实需要括号:
166166

167167
```html
168168
<input type="button" id="button" onclick="sayThanks()">
169169
```
170170

171-
这个区别很容易解释。当浏览器读取 HTML 特性(attribute)时,浏览器将会使用 **特性中的内容** 创建一个处理程序`sayThanks()`
171+
这个区别很容易解释。当浏览器读取 HTML 特性(attribute)时,浏览器将会使用 **特性中的内容** 创建一个处理程序。
172172

173173
所以,标记(markup)会生成下面这个属性:
174174
```js
175175
button.onclick = function() {
176176
*!*
177-
sayThanks(); // 特性中的内容
177+
sayThanks(); // <-- 特性(attribute)中的内容变到了这里
178178
*/!*
179179
};
180180
```
181181

182-
**使用函数,而不是字符串。**
183-
184-
`elem.onclick = "alert(1)"` 也可以执行。它能执行是出于兼容性,但强烈建议不要使用这种方式。
185-
186182
**不要对处理程序使用 `setAttribute`**
187183

188184
这样的调用会失效:
@@ -201,7 +197,7 @@ document.body.setAttribute('onclick', function() { alert(1) });
201197

202198
上述分配处理程序的方式的根本问题是 —— 我们不能为一个事件分配多个处理程序。
203199

204-
例如,在我们点击了一个按钮时,我们代码中的一部分想要高亮显示这个按钮,另一部分则想要显示一条消息。
200+
假设,在我们点击了一个按钮时,我们代码中的一部分想要高亮显示这个按钮,另一部分则想要显示一条消息。
205201

206202
我们想为此事件分配两个处理程序。但是,新的 DOM 属性将覆盖现有的 DOM 属性:
207203

@@ -229,8 +225,7 @@ element.addEventListener(event, handler[, options]);
229225
: 具有以下属性的附加可选对象:
230226
- `once`:如果为 `true`,那么会在被触发后自动删除监听器。
231227
- `capture`:事件处理的阶段,我们稍后将在 <info:bubbling-and-capturing> 一章中介绍。由于历史原因,`options` 也可以是 `false/true`,它与 `{capture: false/true}` 相同。
232-
- `passive`:如果为 `true`,那么处理程序将不会 `preventDefault()`,我们稍后将在 <info:default-browser-action> 一章中介绍。
233-
228+
- `passive`:如果为 `true`,那么处理程序将不会调用 `preventDefault()`,我们稍后将在 <info:default-browser-action> 一章中介绍。
234229

235230
要移除处理程序,可以使用 `removeEventListener`
236231

@@ -249,7 +244,7 @@ elem.addEventListener( "click" , () => alert('Thanks!'));
249244
elem.removeEventListener( "click", () => alert('Thanks!'));
250245
```
251246
252-
处理程序不会被移除,因为 `removeEventListener` 获取了另一个函数 —— 使用相同的代码,但这并不起作用。
247+
处理程序不会被移除,因为 `removeEventListener` 获取了另一个函数 —— 使用相同的代码,但这并不起作用,因为它是一个不同的函数对象
253248
254249
下面是正确方法:
255250
@@ -291,31 +286,33 @@ input.removeEventListener("click", handler);
291286
正如我们在上面这个例子中所看到的,我们可以 **同时** 使用 DOM 属性和 `addEventListener` 来设置处理程序。但通常我们只使用其中一种方式。
292287

293288
````warn header="对于某些事件,只能通过 `addEventListener` 设置处理程序"
294-
有些事件无法通过 DOM 属性进行分配。必须使用 `addEventListener`
289+
有些事件无法通过 DOM 属性进行分配。只能使用 `addEventListener`
295290

296291
例如,`DOMContentLoaded` 事件,该事件在文档加载完成并且 DOM 构建完成时触发。
297292

298293
```js
294+
// 永远不会运行
299295
document.onDOMContentLoaded = function() {
300-
alert("DOM built"); // 永远不会运行
296+
alert("DOM built");
301297
};
302298
```
303299

304300
```js
301+
// 这种方式可以运行
305302
document.addEventListener("DOMContentLoaded", function() {
306-
alert("DOM built"); // 这种方式可以运行
303+
alert("DOM built");
307304
});
308305
```
309306
所以 `addEventListener` 更通用。虽然这样的事件是特例而不是规则。
310307
````
311308
312309
## 事件对象
313310
314-
为了正确处理事件,我们需要更深入地了解发生了什么。不仅仅是 "click" 或 "keypress",还包括鼠标指针的坐标是什么?按下了哪个键?等等。
311+
为了正确处理事件,我们需要更深入地了解发生了什么。不仅仅是 "click" 或 "keydown",还包括鼠标指针的坐标是什么?按下了哪个键?等等。
315312
316313
当事件发生时,浏览器会创建一个 **`event` 对象**,将详细信息放入其中,并将其作为参数传递给处理程序。
317314
318-
下面是一个从 `event` 对象获取鼠标坐标的示例
315+
下面是一个从 `event` 对象获取鼠标指针的坐标的示例
319316
320317
```html run
321318
<input type="button" value="Click me" id="elem">
@@ -338,11 +335,11 @@ document.addEventListener("DOMContentLoaded", function() {
338335
: 处理事件的元素。这与 `this` 相同,除非处理程序是一个箭头函数,或者它的 `this` 被绑定到了其他东西上,之后我们就可以从 `event.currentTarget` 获取元素了。
339336
340337
`event.clientX / event.clientY`
341-
: 鼠标事件的指针的窗口相对坐标
338+
: 指针事件(pointer event)的指针的窗口相对坐标
342339
343-
还有很多属性。它们取决于事件类型,因此,稍后我们将详细讨论不同事件,那时我们再对其进行详细研究。
340+
还有很多属性。其中很多都取决于事件类型:键盘事件具有一组属性,指针事件具有另一组属性,稍后我们将详细讨论不同事件,那时我们再对其进行详细研究。
344341
345-
````smart header="也可以从 HTML 中访问 `event` 对象"
342+
````smart header="`event` 对象在 HTML 处理程序中也可用"
346343
如果我们在 HTML 中分配了一个处理程序,那么我们也可以使用 `event` 对象,像这样:
347344
348345
```html autorun height=60
@@ -364,15 +361,17 @@ document.addEventListener("DOMContentLoaded", function() {
364361
<button id="elem">Click me</button>
365362

366363
<script>
367-
elem.addEventListener('click', {
364+
let obj = {
368365
handleEvent(event) {
369366
alert(event.type + " at " + event.currentTarget);
370367
}
371-
});
368+
};
369+
370+
elem.addEventListener('click', obj);
372371
</script>
373372
```
374373

375-
正如我们所看到的,当 `addEventListener` 接收一个对象作为处理程序时,在事件发生时,它就会调用 `object.handleEvent(event)` 来处理事件。
374+
正如我们所看到的,当 `addEventListener` 接收一个对象作为处理程序时,在事件发生时,它就会调用 `obj.handleEvent(event)` 来处理事件。
376375

377376
我们也可以对此使用一个类:
378377

2-ui/2-events/03-event-delegation/article.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,8 @@ table.onclick = function(event) {
101101

102102
解释:
103103
1. `elem.closest(selector)` 方法返回与 `selector` 匹配的最近的祖先。在我们的例子中,我们从源元素开始向上寻找 `<td>`
104-
2. 如果 `event.target` 不在任何 `<td>` 中,那么调用将返回 `null`,我们不需要做任何事情
105-
3. 在嵌套的表格的情况下`event.target` 可能是位于当前表格之外的 `<td>`。因此我们需要检查这是否是 **我们的表格中的** `<td>`
104+
2. 如果 `event.target` 不在任何 `<td>` 中,那么调用将立即返回,因为这里没有什么事儿可做
105+
3. 对于嵌套的表格`event.target` 可能是一个 `<td>`,但位于当前表格之外。因此我们需要检查它是否是 **我们的表格中的** `<td>`
106106
4. 如果是的话,就高亮显示它。
107107

108108
最终,我们得到了一个快速、高效的用于高亮显示的代码,该代码与表格中的 `<td>` 的数量无关。

0 commit comments

Comments
 (0)