Skip to content

Commit 6276b55

Browse files
authored
Update translation of 2-ui/99-ui-misc/01-mutation-observer and 1-js/05-data-types/01-primitives-methods/article.md (javascript-tutorial#707)
Update translation of 2-ui/99-ui-misc/01-mutation-observer and 1-js/05-data-types/01-primitives-methods/article.md (javascript-tutorial#707)
1 parent 2fc1a2a commit 6276b55

2 files changed

Lines changed: 86 additions & 82 deletions

File tree

1-js/05-data-types/01-primitives-methods/article.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
# 原始(primitive)类型的方法
1+
# 原始类型的方法
22

33
JavaScript 允许我们像使用对象一样使用原始类型(字符串,数字等)。JavaScript 还提供了这样的调用方法。我们很快就会学习它们,但是首先我们将了解它的工作原理,毕竟基本类型不是对象(在这里我们会分析的更加清楚)。
44

5-
我们来看看基原始类型和对象之间的关键区别
5+
我们来看看原始类型和对象之间的关键区别
66

7-
一个原始值
7+
一个原始值
88

99
- 是原始类型中的一种值。
10-
- 在 JavaScript 中有 7 种原始类型:`string``number``bigint``boolean``symbol``null``undefined`
10+
- 在 JavaScript 中有 7 种原始类型:`string``number``bigint``boolean``symbol``null``undefined`
1111

12-
一个对象
12+
一个对象
1313

1414
- 能够存储多个值作为属性。
1515
- 可以使用大括号 `{}` 创建对象,例如:`{name: "John", age: 30}`。JavaScript 中还有其他种类的对象,例如函数就是对象。
Lines changed: 81 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11

22
# DOM 变动观察器(Mutation observer)
33

4-
`MutationObserver` 是一个内置对象,它监控 DOM 元素,在其发生变动时触发回调
4+
`MutationObserver` 是一个内建对象,它观察 DOM 元素,在其发生更改时触发回调
55

6-
我们将首先看一下语法,然后研究实际的用例
6+
我们将首先看一下语法,然后探究一个实际的用例,以了解它在什么地方有用
77

88
## 语法
99

1010
`MutationObserver` 使用简单。
1111

12-
首先,我们创建一个带有回调函数(callback-function)的观察器
12+
首先,我们创建一个带有回调函数的观察器
1313

1414
```js
1515
let observer = new MutationObserver(callback);
@@ -21,32 +21,32 @@ let observer = new MutationObserver(callback);
2121
observer.observe(node, config);
2222
```
2323

24-
`config` 是一个带布尔选项的对象,该布尔选项表示“将对哪些变动做出反应”:
25-
- `childList` `node` 的直接子节点的变动
26-
- `subtree` `node` 的所有后代节点的变动
27-
- `attributes` `node` 的属性
28-
- `attributeFilter` - 一组属性名称,只监控选定的属性
29-
- `characterData` - 是否监测 `node.data`(文本内容),
24+
`config` 是一个具有布尔选项的对象,该布尔选项表示“将对哪些更改做出反应”:
25+
- `childList` —— `node` 的直接子节点的更改
26+
- `subtree` —— `node` 的所有后代的更改
27+
- `attributes` —— `node` 的特性(attribute)
28+
- `attributeFilter` —— 特性名称数组,只观察选定的特性
29+
- `characterData` —— 是否观察 `node.data`(文本内容),
3030

3131
其他几个选项:
32-
- `attributeOldValue` 如果为 `true`则将属性的旧值和新值都传递给回调函数(参见下文),否则只传新值(需要 `attributes` 选项),
33-
- `characterDataOldValue` 如果为 `true`,则将 `node.data` 的旧值和新值都传递给回调函数(参见下文),否则只传新值(需要 `characterData` 选项)。
32+
- `attributeOldValue` —— 如果为 `true`则将特性的旧值和新值都传递给回调(参见下文),否则只传新值(需要 `attributes` 选项),
33+
- `characterDataOldValue` —— 如果为 `true`,则将 `node.data` 的旧值和新值都传递给回调(参见下文),否则只传新值(需要 `characterData` 选项)。
3434

35-
发生任何变动后,便执行 “回调” 函数:将变动作为一个 [MutationRecord](https://dom.spec.whatwg.org/#mutationrecord) 对象列表传入第一个参数,而观察器本身作为第二个参数
35+
然后,在发生任何更改后,将执行“回调”:更改被作为一个 [MutationRecord](https://dom.spec.whatwg.org/#mutationrecord) 对象列表传入第一个参数,而观察器自身作为第二个参数
3636

3737
[MutationRecord](https://dom.spec.whatwg.org/#mutationrecord) 对象具有以下属性:
3838

39-
- `type` 变动类型,可以是以下类型中的一个
40-
- `"attributes"`属性被修改了
41-
- `"characterData"`:数据被修改了,用于文本节点
42-
- `"childList"`:添加/删除了子元素
43-
- `target` - 变动发生在何处`"attributes"` 所在的元素,`"characterData"` 所在的文本节点,或 `"childList"` 变动了的某元素
44-
- `addedNodes/removedNodes` 添加/删除的节点
45-
- `previousSibling/nextSibling` 添加/删除的节点的前后相邻节点
46-
- `attributeName/attributeNamespace` - 被更改的属性的名称/命名空间(用于 XML),
47-
- `oldValue` 之前的值,仅用于属性或文本变动,如果设置了相应选项 `attributeOldValue`/`characterDataOldValue`
39+
- `type` —— 变动类型,以下类型之一
40+
- `"attributes"`特性被修改了,
41+
- `"characterData"`:数据被修改了,用于文本节点
42+
- `"childList"`:添加/删除了子元素
43+
- `target` —— 更改发生在何处`"attributes"` 所在的元素,`"characterData"` 所在的文本节点,或 `"childList"` 变动所在的元素
44+
- `addedNodes/removedNodes` —— 添加/删除的节点
45+
- `previousSibling/nextSibling` —— 添加/删除的节点的上一个/下一个兄弟节点,
46+
- `attributeName/attributeNamespace` —— 被更改的特性的名称/命名空间(用于 XML),
47+
- `oldValue` —— 之前的值,仅适用于特性或文本更改,如果设置了相应选项 `attributeOldValue`/`characterDataOldValue`
4848

49-
例如,这里有一个 `<div>`具有 `contentEditable` 属性。该属性用于聚焦和编辑节点
49+
例如,这里有一个 `<div>`它具有 `contentEditable` 特性。该特性使我们可以聚焦和编辑元素
5050

5151
```html run
5252
<div contentEditable id="elem">Click and <b>edit</b>, please</div>
@@ -56,27 +56,27 @@ let observer = new MutationObserver(mutationRecords => {
5656
console.log(mutationRecords); // console.log(the changes)
5757
});
5858
59-
// 监控属性外的所有变动
59+
// 观察除了特性之外的所有变动
6060
observer.observe(elem, {
61-
childList: true, // 监控直接子节点
62-
subtree: true, // 及其后代节点
63-
characterDataOldValue: true // 将旧数据传递给回调函数
61+
childList: true, // 观察直接子节点
62+
subtree: true, // 及其更低的后代节点
63+
characterDataOldValue: true // 将旧的数据传递给回调
6464
});
6565
</script>
6666
```
6767

68-
现在,如果我们更改 `<b>edit</b>` 内的文本,便有了一个变动
68+
如果我们在浏览器中运行上面这段代码,并聚焦到给定的 `<div>` 上,然后更改 `<b>edit</b>` 中的文本,`console.log` 将显示一个变动
6969

7070
```js
7171
mutationRecords = [{
7272
type: "characterData",
7373
oldValue: "edit",
7474
target: <text node>,
75-
// 其他属性留空
75+
// 其他属性为空
7676
}];
7777
```
7878

79-
如果我们选择并同时删除 `<b>edit</b>`就会有多个变动。
79+
如果我们进行更复杂的编辑操作,例如删除 `<b>edit</b>`那么变动事件可能会包含多个变动记录:
8080

8181
```js
8282
mutationRecords = [{
@@ -85,39 +85,39 @@ mutationRecords = [{
8585
removedNodes: [<b>],
8686
nextSibling: <text node>,
8787
previousSibling: <text node>
88-
// 其他属性留空
88+
// 其他属性为空
8989
}, {
9090
type: "characterData"
9191
target: <text node>
92-
// ……变动的详细信息取决于浏览器如何处理此类删除事件
92+
// ...变动的详细信息取决于浏览器如何处理此类删除
9393
// 它可能是将两个相邻的文本节点 "edit " 和 ", please" 合并成一个节点,
94-
// 或将它们各自作为单独的文本节点
94+
// 或者可能将它们留在单独的文本节点中
9595
}];
9696
```
9797

98-
因此,`MutationObserver` 允许对 DOM 子树中的任何更改做出反应
98+
因此,`MutationObserver` 允许对 DOM 子树中的任何更改作出反应
9999

100100
## 用于集成
101101

102-
这在什么时候可能有用
102+
在什么时候可能有用
103103

104-
想象一下,当您在页面上附加了一个第三方脚本,想在页面上添加一个有用的功能,但也同时增添了一些不必要的功能,比如,显示了广告 `<div class="ads">Unwanted ads</div>`
104+
想象一下,你需要添加一个第三方脚本,该脚本不仅包含有用的功能,还会执行一些我们不想要的操作,例如显示广告 `<div class="ads">Unwanted ads</div>`
105105

106-
当然,第三方脚本不会提供删除方法
106+
当然,第三方脚本没有提供删除它的机制
107107

108-
使用 `MutationObserver`我们可以监测到这类元素何时出现在我们的 DOM 中,然后将其删除,并同时保留有用的功能。当然,该脚本的创建者不会开心的,毕竟您拿走他们有用的东西却把广告删除了
108+
使用 `MutationObserver`我们可以监测到我们不需要的元素何时出现在我们的 DOM 中,并将其删除
109109

110-
还有一些其他情况如,第三方脚本会将某些内容添加到我们的文档中,出现这种情况时,我们希望能监测到,并动态调整大小以适应页面等
110+
还有一些其他情况,例如第三方脚本会将某些内容添加到我们的文档中,并且我们希望检测出这种情况何时发生,以调整页面,动态调整某些内容的大小等
111111

112-
`MutationObserver` 可以轻松处理此问题
112+
`MutationObserver` 使我们能够实现这种需求
113113

114114
## 用于架构
115115

116-
从架构的角度来看,`MutationObserver` 也有不错的适用场景
116+
从架构的角度来看,在某些情况下,`MutationObserver` 有不错的作用
117117

118-
假设我们在建一个有关编程的网站。自然地,文章和其他材料中可能包含源代码片段
118+
假设我们正在建立一个有关编程的网站。自然地,文章和其他材料中可能包含源代码段
119119

120-
这些代码片段在 HTML 标记中如下所示
120+
HTML 标记(markup)中的此类片段如下所示
121121

122122
```html
123123
...
@@ -128,29 +128,29 @@ mutationRecords = [{
128128
...
129129
```
130130

131-
另外,我们还将在网站上使用 JavaScript 高亮显示库,例如 [Prism.js](https://prismjs.com/)。调用 `Prism.highlightElem(pre)` 会检查此类 `pre` 元素的内容,并在其中添加特殊标记和样式,进行彩色语法高亮显示,类似于您在本页面的示例中看到的那样
131+
另外,我们还将在网站上使用 JavaScript 高亮显示库,例如 [Prism.js](https://prismjs.com/)。调用 `Prism.highlightElem(pre)` 会检查此类 `pre` 元素的内容,并在其中添加特殊标签(tag)和样式,以进行彩色语法高亮显示,类似于你在本文的示例中看到的那样
132132

133-
那什么时候运行该高亮显示方法呢?我们可以在 `DOMContentLoaded` 事件触发时运行,或在页尾运行。到那时,DOM 已加载完毕,我们可以搜索元素 `pre[class*="language"]` 并调用 `Prism.highlightElem`
133+
那什么时候运行该高亮显示方法呢?我们可以在 `DOMContentLoaded` 事件中或者在页面尾部运行。到那时,我们的 DOM 已准备就绪,我们可以搜索元素 `pre[class*="language"]` 并对其调用 `Prism.highlightElem`
134134

135135
```js
136-
// 在页面上高亮显示所有代码片段
136+
// 高亮显示页面上的所有代码段
137137
document.querySelectorAll('pre[class*="language"]').forEach(Prism.highlightElem);
138138
```
139139

140-
到目前为止,一切都很简单,对吧?HTML 中有 `<pre>` 代码片段,并高亮显示了
140+
到目前为止,一切都很简单,对吧?HTML 中有 `<pre>` 代码段,我们高亮显示它们
141141

142-
现在继续。假设我们要从服务器动态获取资料。我们会在 [后续教程](info:fetch) 中学习怎么做。当前我们只关心从网络服务器获取 HTML 文章后按需显示
142+
现在让我们继续。假设我们要从服务器动态获取资料。我们将 [在本教程的后续章节](info:fetch) 中学习进行此操作的方法。目前,只需要关心我们从网络服务器获取 HTML 文章并按需显示
143143

144144
```js
145145
let article = /* 从服务器获取新内容 */
146146
articleElem.innerHTML = article;
147147
```
148148

149-
新的 `article` HTML 可能包含代码片段。我们需要对其调用 `Prism.highlightElem`否则它们将不会高亮显示
149+
新的 `article` HTML 可能包含代码段。我们需要对其调用 `Prism.highlightElem`否则它们将不会被高亮显示
150150

151-
**对于动态加载的文章,在何处何时调用 `Prism.highlightElem`**
151+
**对于动态加载的文章,应该在何处何时调用 `Prism.highlightElem`**
152152

153-
我们可以对加载文章的那段代码调用该方法,如下所示:
153+
我们可以将该调用附加到加载文章的代码中,如下所示:
154154

155155
```js
156156
let article = /* 从服务器获取新内容 */
@@ -162,38 +162,38 @@ snippets.forEach(Prism.highlightElem);
162162
*/!*
163163
```
164164

165-
……但是,想象一下,代码中有很多地方可以加载内容:文章、测验、论坛帖子。我们需要在所有地方都进行高亮显示调用吗?那不太好办,也很容易遗漏
165+
……但是,想象一下,代码中有很多地方可以加载内容:文章,测验,论坛帖子。我们是否需要在每个地方都附加一个高亮显示调用?那不太方便,也很容易忘记
166166

167-
而且,如果内容是由第三方模块加载的,怎么办?例如,我们有一个由他人编写的论坛,可以动态加载内容,我们想在论坛中添加语法高亮显示功能。没有人喜欢再接入第三方脚本
167+
并且,如果内容是由第三方模块加载的,该怎么办?例如,我们有一个由其他人编写的论坛,该论坛可以动态加载内容,并且我们想为其添加语法高亮显示。没有人喜欢修补第三方脚本
168168

169169
幸运的是,还有另一种选择。
170170

171-
我们可以使用 `MutationObserver` ,它能自动检测何时在页面中插入了代码片段,并高亮显示之
171+
我们可以使用 `MutationObserver` 来自动检测何时在页面中插入了代码段,并高亮显示之它们
172172

173-
因此,我们在一个地方处理高亮显示功能,不再需要集成
173+
因此,我们在一个地方处理高亮显示功能,从而使我们无需集成它
174174

175175
### 动态高亮显示示例
176176

177-
这是运行示例
177+
这是一个工作示例
178178

179-
如果运行此代码,它将开始监测下面的元素,并高亮显示该元素处出现的任何代码段
179+
如果你运行这段代码,它将开始观察下面的元素,并高亮显示现在此处的所有代码段
180180

181181
```js run
182182
let observer = new MutationObserver(mutations => {
183183

184184
for(let mutation of mutations) {
185-
// 检查新节点,是否有需要高亮的
185+
// 检查新节点,有什么需要高亮显示的吗
186186

187187
for(let node of mutation.addedNodes) {
188-
//我们只跟踪元素,忽略其他节点(例如文本节点)
188+
// 我们只跟踪元素,跳过其他节点(例如文本节点)
189189
if (!(node instanceof HTMLElement)) continue;
190190

191191
// 检查插入的元素是否为代码段
192192
if (node.matches('pre[class*="language-"]')) {
193193
Prism.highlightElement(node);
194194
}
195195

196-
// 或在子树的某处可能有一个代码片段
196+
// 或者可能在子树的某个地方有一个代码段
197197
for(let elem of node.querySelectorAll('pre[class*="language-"]')) {
198198
Prism.highlightElement(elem);
199199
}
@@ -207,56 +207,60 @@ let demoElem = document.getElementById('highlight-demo');
207207
observer.observe(demoElem, {childList: true, subtree: true});
208208
```
209209

210-
下面有一个 HTML 元素和 JavaScript,该脚本使用 `innerHTML` 动态填充 HTML 元素
210+
下面有一个 HTML 元素,以及使用 `innerHTML` 动态填充它的 JavaScript
211211

212-
请先运行前面的代码(如前述,监测到该元素),然后运行下面的代码。您将看到 `MutationObserver` 如何检测并高亮显示该代码段
212+
请先运行前面那段代码(上面那段,观察元素),然后运行下面这段代码。你将看到 `MutationObserver` 是如何检测并高亮显示代码段的
213213

214-
<p id="highlight-demo" style="border: 1px solid #ddd">A demo-element with <code>id="highlight-demo"</code>, run the code above to observe it.</p>
214+
<p id="highlight-demo" style="border: 1px solid #ddd">一个具有 <code>id="highlight-demo"</code> 的示例元素,运行上面那段代码来观察它。</p>
215215

216-
以下代码填充了其 `innerHTML`。请先运行上面的代码,它将监测并高亮显示新内容
216+
下面这段代码填充了其 `innerHTML`,这导致 `MutationObserver` 作出反应,并突出显示其内容
217217

218218
```js run
219219
let demoElem = document.getElementById('highlight-demo');
220220

221221
// 动态插入带有代码段的内容
222-
demoElem.innerHTML = `A code snippet is below:
222+
demoElem.innerHTML = `下面是一个代码段:
223223
<pre class="language-javascript"><code> let hello = "world!"; </code></pre>
224-
<div>Another one:</div>
224+
<div>另一个代码段:</div>
225225
<div>
226226
<pre class="language-css"><code>.class { margin: 5px; } </code></pre>
227227
</div>
228228
`;
229229
```
230230

231-
现在我们有了 `MutationObserver`它可以跟踪在被监测的元素或整个“文档”中的所有高亮显示。我们可以在 HTML 中随意添加/删除代码段。
231+
现在我们有了 `MutationObserver`它可以跟踪观察到的元素中的,或者整个 `document` 中的所有高亮显示。我们可以在 HTML 中添加/删除代码段,而无需考虑高亮问题
232232

233233
## 其他方法
234234

235-
有一个方法可以停止监测节点
235+
有一个方法可以停止观察节点
236236

237-
- `observer.disconnect()` - 停止监测
237+
- `observer.disconnect()` —— 停止观察
238238

239-
跟它经常一起使用的另一个方法:
239+
当我们停止观察时,观察器可能尚未处理某些更改。
240240

241-
- `mutationRecords = observer.takeRecords()` - 获取尚未处理的变动记录列表,即发生了变动但回调函数还没有处理它们。
241+
- `observer.takeRecords()` —— 获取尚未处理的变动记录列表,表中记录的是已经发生,但回调暂未处理的变动。
242+
243+
这些方法可以一起使用,如下所示:
242244

243245
```js
244-
// 我们想停止监测变动
246+
// 我们想要停止跟踪变动
245247
observer.disconnect();
246248

247-
// 它可能尚未处理某些变动
249+
// 处理未处理的变动
248250
let mutationRecords = observer.takeRecords();
249-
// 处理 mutationRecords
251+
...
250252
```
251253

252-
## 垃圾回收
254+
```smart header="垃圾回收"
255+
观察器在内部对节点使用弱引用。也就是说:如果一个节点被从 DOM 中删除了,并且该节点变得不可访问,那么它就会被垃圾回收。
253256
254-
观察器在内部对节点使用弱引用。即:如果一个节点从 DOM 中删除了,便访问不到了,那么它就成了要回收的垃圾,观察器不会阻止这种情况。
257+
观察到 DOM 节点这一事实并不能阻止垃圾回收。
258+
```
255259

256260
## 总结
257261

258-
`MutationObserver` 可以监测 DOM 的变动如:属性、添加/删除的元素文本内容。
262+
`MutationObserver` 可以对 DOM 的变化作出反应:特性(attribute),添加/删除的元素文本内容。
259263

260264
我们可以用它来跟踪代码其他部分引入的更改,以及与第三方脚本集成。
261265

262-
`MutationObserver` 可以监测任何更改。配置选项“监测哪些内容”用于优化监测,节省不必要的回调调用
266+
`MutationObserver` 可以跟踪任何更改。`config` “要观察的内容”选项用于优化,避免不必要的回调调用以节省资源

0 commit comments

Comments
 (0)