Skip to content

Commit da15130

Browse files
committed
修改bom/mutation Observer
1 parent 8f0e4f3 commit da15130

File tree

3 files changed

+177
-104
lines changed

3 files changed

+177
-104
lines changed

dom/mutationobserver.md

Lines changed: 94 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@ Mutation Observer有以下特点:
2626

2727
{% highlight javascript %}
2828

29-
var MutationObserver = window.MutationObserver ||
30-
window.WebKitMutationObserver ||
31-
window.MozMutationObserver;
29+
var MutationObserver = window.MutationObserver
30+
|| window.WebKitMutationObserver
31+
|| window.MozMutationObserver;
3232

3333
var observeMutationSupport = !!MutationObserver;
3434

@@ -40,7 +40,7 @@ var observeMutationSupport = !!MutationObserver;
4040

4141
{% highlight javascript %}
4242

43-
var observer = new MutationObserver( callback );
43+
var observer = new MutationObserver(callback);
4444

4545
{% endhighlight %}
4646

@@ -50,20 +50,20 @@ observe方法指定所要观察的DOM元素,以及所要观察的特定变动
5050

5151
{% highlight javascript %}
5252

53-
var article = document.querySelector( 'article' );
53+
var article = document.querySelector('article');
5454

5555
var options = {
56-
'childList': true,
57-
'attributes':true
56+
'childList': true,
57+
'attributes':true
5858
} ;
5959

60-
observer.observe( article, options );
60+
observer.observe(article, options);
6161

6262
{% endhighlight %}
6363

6464
上面代码首先指定,所要观察的DOM元素是article,然后,指定所要观察的变动是子元素变动和属性变动。最后,将这两个限定条件作为参数,传入observer对象的observe方法。
6565

66-
Mutation Observer所观察的DOM变动(即上面代码的option对象),包含以下类型:
66+
Mutation Observer所观察的DOM变动(即上面代码的options对象),包含以下类型:
6767

6868
- **childList**:子元素的变动。
6969
- **attributes**:属性的变动。
@@ -120,17 +120,17 @@ MutationRecord对象包含了DOM的相关信息,有如下属性:
120120
{% highlight javascript %}
121121

122122
var callback = function(records){
123-
records.map(function(record){
124-
console.log('Mutation type: ' + record.type);
125-
console.log('Mutation target: ' + record.target);
126-
});
123+
records.map(function(record){
124+
console.log('Mutation type: ' + record.type);
125+
console.log('Mutation target: ' + record.target);
126+
});
127127
};
128128

129129
var mo = new MutationObserver(callback);
130130

131131
var option = {
132-
'childList': true,
133-
'subtree': true
132+
'childList': true,
133+
'subtree': true
134134
};
135135

136136
mo.observe(document.body, option);
@@ -146,18 +146,18 @@ mo.observe(document.body, option);
146146
{% highlight javascript %}
147147

148148
var callback = function(records){
149-
records.map(function(record){
150-
console.log('Previous attribute value: ' + record.oldValue);
151-
});
149+
records.map(function(record){
150+
console.log('Previous attribute value: ' + record.oldValue);
151+
});
152152
};
153153

154154
var mo = new MutationObserver(callback);
155155

156156
var element = document.getElementById('#my_element');
157157

158158
var options = {
159-
'attributes': true,
160-
'attributeOldValue': true
159+
'attributes': true,
160+
'attributeOldValue': true
161161
}
162162

163163
mo.observe(element, options);
@@ -166,9 +166,83 @@ mo.observe(element, options);
166166

167167
上面代码先设定追踪属性变动('attributes': true),然后设定记录变动前的值。实际发生变动时,会将变动前的值显示在控制台。
168168

169+
### 取代DOM的ready方法
170+
171+
网页加载的时候,DOM元素是一个接一个生成的,因此只要跟踪DOM的变动,就能在第一时间触发相关事件,因此也就没有必要使用DOM的ready方法。
172+
173+
```javascript
174+
var observer = new MutationObserver(callback);
175+
observer.observe(document.documentElement, {
176+
childList: true,
177+
subtree: true
178+
});
179+
```
180+
181+
上面代码中,监听document.documentElement(即HTML元素)的子元素的变动,subtree属性指定监听还包括子元素的下级元素。因此,任意一个网页元素一旦生成,就能立刻被监听到。
182+
183+
下面的代码,使用MutationObserver对象封装一个监听DOM生成的函数。
184+
185+
```javascript
186+
187+
(function(win){
188+
'use strict';
189+
190+
var listeners = [];
191+
var doc = win.document;
192+
var MutationObserver = win.MutationObserver || win.WebKitMutationObserver;
193+
var observer;
194+
195+
function ready(selector, fn){
196+
// 储存选择器和回调函数
197+
listeners.push({
198+
selector: selector,
199+
fn: fn
200+
});
201+
if(!observer){
202+
// 监听document变化
203+
observer = new MutationObserver(check);
204+
observer.observe(doc.documentElement, {
205+
childList: true,
206+
subtree: true
207+
});
208+
}
209+
// 检查该元素是否已经在DOM中
210+
check();
211+
}
212+
213+
function check(){
214+
// 检查DOM元素是否匹配已储存的元素
215+
for(var i = 0; i < listeners.length; i++){
216+
var listener = listeners[i];
217+
// 检查指定元素是否有匹配
218+
var elements = doc.querySelectorAll(listener.selector);
219+
for(var j = 0; j < elements.length; j++){
220+
var element = elements[j];
221+
// 确保回调函数只会对该元素调用一次
222+
if(!element.ready){
223+
element.ready = true;
224+
// 对该元素调用回调函数
225+
listener.fn.call(element, element);
226+
}
227+
}
228+
}
229+
}
230+
231+
// 对外暴露ready
232+
win.ready = ready;
233+
234+
})(this);
235+
236+
ready('.foo', function(element){
237+
// ...
238+
});
239+
240+
```
241+
169242
## 参考链接
170243

171244
- Tiffany Brown, [Getting to know mutation observers](http://dev.opera.com/articles/view/mutation-observers-tutorial/)
172245
- Michal Budzynski, [JavaScript: The less known parts. DOM Mutations](http://michalbe.blogspot.com/2013/04/javascript-less-known-parts-dom.html)
173246
- Jeff Griffiths, [DOM MutationObserver – reacting to DOM changes without killing browser performance](https://hacks.mozilla.org/2012/05/dom-mutationobserver-reacting-to-dom-changes-without-killing-browser-performance/)
174247
- Addy Osmani, [Detect, Undo And Redo DOM Changes With Mutation Observers](http://addyosmani.com/blog/mutation-observers/)
248+
- Ryan Morr, [Using Mutation Observers to Watch for Element Availability](http://ryanmorr.com/using-mutation-observers-to-watch-for-element-availability/)

grammar/object.md

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@ modifiedOn: 2014-01-17
1212

1313
对象(object)是JavaScript的核心概念,也是最重要的数据类型。JavaScript的所有数据都可以被视为对象。
1414

15-
简单说,所谓对象,就是一种无序的数据集合,由若干个“键值对”(key-value)构成。
15+
简单说,所谓对象,就是一种无序的数据集合,由若干个“键值对”(key-value)构成。
1616

1717
{% highlight javascript %}
1818

1919
var o = {
20-
p: "Hello World"
20+
p: "Hello World"
2121
};
2222

2323
{% endhighlight %}
@@ -31,7 +31,7 @@ var o = {
3131
{% highlight javascript %}
3232

3333
var o = {
34-
"p": "Hello World"
34+
"p": "Hello World"
3535
};
3636

3737
{% endhighlight %}
@@ -41,9 +41,9 @@ var o = {
4141
{% highlight javascript %}
4242

4343
var o = {
44-
"1p": "Hello World",
45-
"h w": "Hello World",
46-
"p+q": "Hello World"
44+
"1p": "Hello World",
45+
"h w": "Hello World",
46+
"p+q": "Hello World"
4747
};
4848

4949
{% endhighlight %}
@@ -57,7 +57,7 @@ var o = {
5757
{% highlight javascript %}
5858

5959
var o = {
60-
p: function(x) {return 2*x;}
60+
p: function(x) {return 2*x;}
6161
};
6262

6363
o.p(1)
@@ -103,7 +103,7 @@ var o3 = Object.create(null);
103103
{% highlight javascript %}
104104

105105
var o = {
106-
p: "Hello World"
106+
p: "Hello World"
107107
};
108108

109109
o.p // "Hello World"
@@ -118,7 +118,7 @@ o["p"] // "Hello World"
118118
{% highlight javascript %}
119119

120120
var o = {
121-
0.7: "Hello World"
121+
0.7: "Hello World"
122122
};
123123

124124
o.["0.7"] // "Hello World"
@@ -157,7 +157,7 @@ if(window['a']) {...} // 不报错
157157
{% highlight javascript %}
158158

159159
if('a' in window) {
160-
...
160+
...
161161
}
162162

163163
{% endhighlight %}
@@ -195,8 +195,8 @@ o.p = 1;
195195
{% highlight javascript %}
196196

197197
var o = {
198-
key1: 1,
199-
key2: 2
198+
key1: 1,
199+
key2: 2
200200
};
201201

202202
Object.keys(o);
@@ -341,10 +341,10 @@ in运算符对继承的属性也有效。
341341

342342
var o = new Object();
343343

344-
o.hasOwnProperty('toString')
344+
o.hasOwnProperty('toString')
345345
// false
346346

347-
'toString' in o
347+
'toString' in o
348348
// true
349349

350350
{% endhighlight %}
@@ -362,7 +362,7 @@ for...in循环用来遍历一个对象的全部属性。
362362
var o = {a:1, b:2, c:3};
363363

364364
for (i in o){
365-
console.log(o[i]);
365+
console.log(o[i]);
366366
}
367367
// 1
368368
// 2
@@ -374,16 +374,22 @@ for (i in o){
374374

375375
{% highlight javascript %}
376376

377+
// name是Person本身的属性
377378
function Person(name) {
378-
this.name = name;
379+
this.name = name;
379380
}
381+
382+
// describe是Person.prototype的属性
380383
Person.prototype.describe = function () {
381-
return 'Name: '+this.name;
384+
return 'Name: '+this.name;
382385
};
383386

384387
var person = new Person('Jane');
388+
389+
// for...in循环会遍历实例自身的属性(name),
390+
// 以及继承的属性(describe)
385391
for (var key in person) {
386-
console.log(key);
392+
console.log(key);
387393
}
388394
// name
389395
// describe
@@ -405,6 +411,8 @@ for (var key in person) {
405411

406412
{% endhighlight %}
407413

414+
为了避免这一点,可以新建一个继承null的对象。由于null没有任何属性,所以新对象也就不会有继承的属性了。
415+
408416
## 类似数组的对象
409417

410418
在JavaScript中,有些对象被称为“类似数组的对象”(array-like object)。意思是,它们看上去很像数组,可以使用length属性,但是它们并不是数组,所以无法使用一些数组的方法。

0 commit comments

Comments
 (0)