@@ -52,41 +52,42 @@ JavaScript(行为)层的地位不应该很显赫,也就是说它不应该
52
52
53
53
## DOM编程
54
54
55
- 操作页面的DOM树是在客户端JavaScript编程中最普遍的动作 。这也是导致开发者头疼的最主要原因(这也导致了JavaScript名声不好),因为DOM方法在不同的浏览器中实现得有很多差异。这也是为什么使用一个抽象了浏览器差异的JavaScript库能显著提高开发速度的原因。
55
+ 操作页面的DOM树是在客户端JavaScript编程中最普遍的行为 。这也是导致开发者头疼的最主要原因(这也导致了JavaScript名声不好),因为DOM方法在不同的浏览器中实现得有很多差异。这也是为什么使用一个抽象了浏览器差异的JavaScript库能显著提高开发速度的原因。
56
56
57
- 我们来看一些在访问和修改DOM树时推荐的模式,主要考虑点是性能方面 。
57
+ 我们来看一些在访问和修改DOM树时推荐的模式,主要考虑性能方面 。
58
58
59
59
### DOM访问
60
60
61
61
DOM操作性能不好,这是影响JavaScript性能的最主要原因。性能不好是因为浏览器的DOM实现通常是和JavaScript引擎分离的。从浏览器的角度来讲,这样做是很有意义的,因为有可能一个JavaScript应用根本不需要DOM,而除了JavaScript之外的其它语言(如IE的VBScript)也可以用来操作页面中的DOM。
62
62
63
63
一个原则就是DOM访问的次数应该被减少到最低,这意味者:
64
64
65
- - 避免在环境中访问DOM
65
+ - 避免在循环中访问DOM
66
66
- 将DOM引用赋给本地变量,然后操作本地变量
67
67
- 当可能的时候使用selectors API
68
- - 遍历HTML collections时缓存length(见第2章 )
68
+ - 遍历HTML collections时缓存 ` length ` (见第二章 )
69
69
70
- 看下面例子中的第二个(better)循环 ,尽管它看起来更长一些,但却要快上几十上百倍(取决于具体浏览器):
70
+ 看下面例子中的第二个循环 ,尽管它看起来更长一些,但却要快上几十上百倍(取决于具体浏览器):
71
71
72
- // antipattern
72
+ // 反模式
73
73
for (var i = 0; i < 100; i += 1) {
74
74
document.getElementById("result").innerHTML += i + ", ";
75
75
}
76
76
77
- // better - update a local variable var i, content = "";
77
+ // 更好的方式 - 更新本地变量
78
+ var i, content = "";
78
79
for (i = 0; i < 100; i += 1) {
79
80
content += i + ",";
80
81
}
81
82
document.getElementById("result").innerHTML += content;
82
83
83
- 在下一个代码片段中,第二个例子(使用了本地变量style )更好,尽管它需要多写一行代码,还需要多定义一个变量:
84
+ 在下一个代码片段中,第二个例子(使用了本地变量 ` style ` )更好,尽管它需要多写一行代码,还需要多定义一个变量:
84
85
85
- // antipattern
86
+ // 反模式
86
87
var padding = document.getElementById("result").style.padding,
87
88
margin = document.getElementById("result").style.margin;
88
89
89
- // better
90
+ // 更好的方式
90
91
var style = document.getElementById("result").style,
91
92
padding = style.padding,
92
93
margin = style.margin;
@@ -96,22 +97,22 @@ DOM操作性能不好,这是影响JavaScript性能的最主要原因。性能
96
97
document.querySelector("ul .selected");
97
98
document.querySelectorAll("#widget .class");
98
99
99
- 这两个方法接受一个CSS选择器字符串,返回匹配这个选择器的DOM列表(译注:querySelector只返回第一个匹配的DOM )。selectors API在现代浏览器(以及IE8+)可用 ,它总是会比你使用其它DOM方法来做同样的选择要快。主流的JavaScript库的最近版本都已经使用了这个API,所以你有理由去检查你的项目 ,确保使用的是最新版本。
100
+ 这两个方法接受一个CSS选择器字符串,返回匹配这个选择器的DOM列表(译注:` querySelector ` 只返回第一个匹配的DOM )。selectors API在现代浏览器(以及IE8+)中可用 ,它总是会比你使用其它DOM方法来做同样的选择要快。主流的JavaScript库的最新版本都已经使用了这个API,所以你应该去检查你的项目 ,确保使用的是最新版本。
100
101
101
- 给你经常访问的元素加上一个id属性也是有好处的,因为document .getElementById(myid)是找到一个DOM元素最容易也是最快的方法。
102
+ 给你经常访问的元素加上一个 ` id ` 属性也是有好处的,因为 ` document .getElementById(myid)` 是找到一个DOM元素最容易也是最快的方法。
102
103
103
104
### DOM操作
104
105
105
- 除了访问DOM元素之外,你可能经常需要改变它们、删除其中的一些或者是添加新的元素。更新DOM会导致浏览器重绘(repaint)屏幕,也经常导致重排(reflow)( 重新计算元素的位置),这些操作代价是很高的。
106
+ 除了访问DOM元素之外,你可能经常需要改变它们、删除其中的一些或者是添加新的元素。更新DOM会导致浏览器重绘(repaint)屏幕,也经常导致重排(reflow, 重新计算元素的位置),这些操作代价是很高的。
106
107
107
- 再说一次,通用的原则仍然是尽量少地更新DOM ,这意味着我们可以将变化集中到一起,然后在“活动的”(live)文档树之外去执行这些变化。
108
+ 还是那句话,原则是尽量少地更新DOM ,这意味着我们可以将变化集中到一起,然后在“活动的”(live)文档树之外去执行这些变化。
108
109
109
110
当你需要添加一棵相对较大的子树的时候,你应该在完成这棵树的构建之后再放到文档树中。为了达到这个目的,你可以使用文档碎片(document fragment)来包含你的节点。
110
111
111
112
不要这样添加节点:
112
113
113
- // antipattern
114
- // appending nodes as they are created
114
+ // 反模式
115
+ // 在节点创建后就插入文档
115
116
116
117
var p, t;
117
118
@@ -145,16 +146,16 @@ DOM操作性能不好,这是影响JavaScript性能的最主要原因。性能
145
146
146
147
document.body.appendChild(frag);
147
148
148
- 这个例子和前面例子中每段更新一次相比,文档树只被更新了一下 ,只导致一次重排/重绘。
149
+ 这个例子和前面例子中每段更新一次相比,文档树只被更新了一次 ,只导致一次重排/重绘。
149
150
150
151
当你添加新的节点到文档中时,文档碎片很有用。当你需要更新已有的节点时,你也可以将这些变化集中。你可以将你要修改的子树的父节点克隆一份,然后对克隆的这份做修改,完成之后再去替换原来的元素。
151
152
152
153
var oldnode = document.getElementById('result'),
153
154
clone = oldnode.cloneNode(true);
154
155
155
- // work with the clone...
156
+ // 修改克隆后的节点……
156
157
157
- // when you're done:
158
+ // 结束修改之后:
158
159
oldnode.parentNode.replaceChild(clone, oldnode);
159
160
160
161
## 事件
0 commit comments