[轉(zhuǎn)]prototype 源碼解讀 超強(qiáng)推薦
更新時(shí)間:2007年02月13日 00:00:00 作者:
dom.js 代碼:
復(fù)制代碼 代碼如下:
/**
2
3 * 根據(jù) class attribute 的名字得到對(duì)象數(shù)組,支持 multiple class
4
5 *
6
7 */
8
9 document.getElementsByClassName = function(className) {
10
11 var children = document.getElementsByTagName('*') || document.all;
12
13 var elements = new Array();
14
15
16 for (var i = 0; i < children.length; i++) {
17
18 var child = children[i];
19
20 var classNames = child.className.split(' ');
21
22 for (var j = 0; j < classNames.length; j++) {
23
24 if (classNames[j] == className) {
25
26 elements.push(child);
27
28 break;
29
30 }
31
32 }
33
34 }
35
36
37 return elements;
38
39 }
40
41
42 /*--------------------------------------------------------------------------*/
43
44
45 /**
46
47 * Element 就象一個(gè) java 的工具類,主要用來(lái) 隱藏/顯示/銷除 對(duì)象,
48
49 * 以及獲取對(duì)象的簡(jiǎn)單屬性。
50
51 *
52
53 */
54
55 var Element = {
56
57 toggle: function() {
58
59 for (var i = 0; i < arguments.length; i++) {
60
61 var element = $(arguments[i]);
62
63 element.style.display =
64
65 (element.style.display == 'none' ? '' : 'none');
66
67 }
68
69 },
70
71
72 hide: function() {
73
74 for (var i = 0; i < arguments.length; i++) {
75
76 var element = $(arguments[i]);
77
78 element.style.display = 'none';
79
80 }
81
82 },
83
84
85 show: function() {
86
87 for (var i = 0; i < arguments.length; i++) {
88
89 var element = $(arguments[i]);
90
91 element.style.display = '';
92
93 }
94
95 },
96
97
98 remove: function(element) {
99
100 element = $(element);
101
102 element.parentNode.removeChild(element);
103
104 },
105
106
107 getHeight: function(element) {
108
109 element = $(element);
110
111 return element.offsetHeight;
112
113 }
114
115 }
116
117
118 /**
119
120 * 為 Element.toggle 做了一個(gè)符號(hào)連接,大概是兼容性的考慮
121
122 */
123
124 var Toggle = new Object();
125
126 Toggle.display = Element.toggle;
127
128
129 /*--------------------------------------------------------------------------*/
130
131
132 /**
133
134 * 動(dòng)態(tài)插入內(nèi)容的實(shí)現(xiàn),MS的Jscript實(shí)現(xiàn)中對(duì)象有一個(gè) insertAdjacentHTML 方法
135
136 * http://msdn.microsoft.com/workshop/
137
138 * author/dhtml/reference/methods/insertadjacenthtml.asp
139
140 * 這里算是一個(gè)對(duì)象形式的封裝。
141
142 */
143
144 Abstract.Insertion = function(adjacency) {
145
146 this.adjacency = adjacency;
147
148 }
149
150
151 Abstract.Insertion.prototype = {
152
153 initialize: function(element, content) {
154
155 this.element = $(element);
156
157 this.content = content;
158
159
160 if (this.adjacency && this.element.insertAdjacentHTML) {
161
162 this.element.insertAdjacentHTML(this.adjacency, this.content);
163
164 } else {
165
166 /**
167
168 * gecko 不支持 insertAdjacentHTML 方法,但可以用如下代碼代替
169
170 */
171
172 this.range = this.element.ownerDocument.createRange();
173
174 /**
175
176 * 如果定義了 initializeRange 方法,則實(shí)行,
177
178 * 這里相當(dāng)與定義了一個(gè)抽象的 initializeRange 方法
179
180 */
181
182 if (this.initializeRange) this.initializeRange();
183
184 this.fragment = this.range.createContextualFragment(this.content);
185
186
187 /**
188
189 * insertContent 也是一個(gè)抽象方法,子類必須實(shí)現(xiàn)
190
191 */
192
193 this.insertContent();
194
195 }
196
197 }
198
199 }
200
201
202 /**
203
204 * prototype 加深了我的體會(huì),就是寫(xiě)js 如何去遵循
205
206 * Don't Repeat Yourself (DRY) 原則
207
208 * 上文中 Abstract.Insertion 算是一個(gè)抽象類,
209
210 * 定義了名為 initializeRange 的一個(gè)抽象方法
211
212 * var Insertion = new Object() 建立一個(gè)命名空間
213
214 * Insertion.Before|Top|Bottom|After 就象是四個(gè)java中
215
216 * 的四個(gè)靜態(tài)內(nèi)部類,而它們分別繼承于
217
218 * Abstract.Insertion,并實(shí)現(xiàn)了initializeRange方法。
219
220 */
221
222 var Insertion = new Object();
223
224
225 Insertion.Before = Class.create();
226
227 Insertion.Before.prototype =
228
229 (new Abstract.Insertion('beforeBegin')).extend({
230
231 initializeRange: function() {
232
233 this.range.setStartBefore(this.element);
234
235 },
236
237
238 /**
239
240 * 將內(nèi)容插入到指定節(jié)點(diǎn)的前面, 與指定節(jié)點(diǎn)同級(jí)
241
242 */
243
244 insertContent: function() {
245
246 this.element.parentNode.insertBefore(this.fragment, this.element);
247
248 }
249
250 });
251
252
253 Insertion.Top = Class.create();
254
255 Insertion.Top.prototype =
256
257 (new Abstract.Insertion('afterBegin')).extend({
258
259 initializeRange: function() {
260
261 this.range.selectNodeContents(this.element);
262
263 this.range.collapse(true);
264
265 },
266
267
268 /**
269
270 * 將內(nèi)容插入到指定節(jié)點(diǎn)的第一個(gè)子節(jié)點(diǎn)前,于是內(nèi)容變?yōu)樵摴?jié)點(diǎn)的第一個(gè)子節(jié)點(diǎn)
271
272 */
273
274 insertContent: function() {
275
276 this.element.insertBefore(this.fragment, this.element.firstChild);
277
278 }
279
280 });
281
282
283 Insertion.Bottom = Class.create();
284
285 Insertion.Bottom.prototype = (new Abstract.Insertion('beforeEnd')).extend({
286
287 initializeRange: function() {
288
289 this.range.selectNodeContents(this.element);
290
291 this.range.collapse(this.element);
292
293 },
294
295
296 /**
297
298 * 將內(nèi)容插入到指定節(jié)點(diǎn)的最后,于是內(nèi)容變?yōu)樵摴?jié)點(diǎn)的最后一個(gè)子節(jié)點(diǎn)
299
300 */
301
302 insertContent: function() {
303
304 this.element.appendChild(this.fragment);
305
306 }
307
308 });
309
310
311
312 Insertion.After = Class.create();
313
314 Insertion.After.prototype = (new Abstract.Insertion('afterEnd')).extend({
315
316 initializeRange: function() {
317
318 this.range.setStartAfter(this.element);
319
320 },
321
322
323 /**
324
325 * 將內(nèi)容插入到指定節(jié)點(diǎn)的后面, 與指定節(jié)點(diǎn)同級(jí)
326
327 */
328
329 insertContent: function() {
330
331 this.element.parentNode.insertBefore(this.fragment,
332
333 this.element.nextSibling);
334
335 }
336
337 });
其他代碼:
prototype 還有兩個(gè)源碼文件 effects.js compat.js 就不貼出來(lái)了。兩者并不常用,effects.js 看example 做花哨的效果還不錯(cuò),不過(guò)代碼中沒(méi)有太多新鮮的東西。
需要指出的就是
compat.js 中 Funcation.prototype.apply 的實(shí)現(xiàn)有兩個(gè)錯(cuò)誤(應(yīng)該是拼寫(xiě)錯(cuò)誤), 我分別貼出來(lái),大家比較一下就清楚了。
復(fù)制代碼 代碼如下:
/* 這是包含錯(cuò)誤的原版本
2
3 if (!Function.prototype.apply) {
4
5 // Based on code from http://www.youngpup.net/
6
7 Function.prototype.apply = function(object, parameters) {
8
9 var parameterStrings = new Array();
10
11 if (!object) object = window;
12
13 if (!parameters) parameters = new Array();
14
15
16 for (var i = 0; i < parameters.length; i++)
17
18 parameterStrings[i] = 'x[' + i + ']'; //Error 1
19
20
21 object.__apply__ = this;
22
23 var result = eval('obj.__apply__(' + //Error 2
24
25 parameterStrings[i].join(', ') + ')');
26
27 object.__apply__ = null;
28
29
30 return result;
31
32 }
33
34 }
35
36 */
37
38
39 if (!Function.prototype.apply) {
40
41 Function.prototype.apply = function(object, parameters) {
42
43 var parameterStrings = new Array();
44
45 if (!object) object = window;
46
47 if (!parameters) parameters = new Array();
48
49
50 for (var i = 0; i < parameters.length; i++)
51
52 parameterStrings[i] = 'parameters[' + i + ']';
53
54
55 object.__apply__ = this;
56
57 var result = eval('object.__apply__(' + parameterStrings.join(', ') + ')');
58
59 object.__apply__ = null;
60
61
62 return result;
63
64 }
65
66 }
接下來(lái)是我模仿著編寫(xiě)的一個(gè) Effect 的一個(gè)子類,用來(lái)實(shí)現(xiàn)閃爍的效果。
復(fù)制代碼 代碼如下:
Effect.Blink = Class.create();
2
3 Effect.Blink.prototype = {
4
5 initialize: function(element, frequency) {
6
7 this.element = $(element);
8
9 this.frequency = frequency?frequency:1000;
10
11 this.element.effect_blink = this;
12
13 this.blink();
14
15 },
16
17
18 blink: function() {
19
20 if (this.timer) clearTimeout(this.timer);
21
22 try {
23
24 this.element.style.visibility =
25
26 this.element.style.visibility == 'hidden'?'visible':'hidden';
27
28 } catch (e) {}
29
30 this.timer = setTimeout(this.blink.bind(this), this.frequency);
31
32 }
33
34 };
使用也很簡(jiǎn)單, 調(diào)用 new Effect.Blink(elementId) 就好了。
通過(guò)對(duì) prototype 源碼的研究,我想我對(duì)javascript又有了一點(diǎn)新的體會(huì),而最大的體會(huì)就是 《Ajax : A New Approach to Web Applications》文章最后作者對(duì)設(shè)計(jì)人員的建議: to forget what we think we know about the limitations of the Web, and begin to imagine a wider, richer range of possibilities.
相關(guān)文章
滾動(dòng)經(jīng)典最新話題[prototype框架]下編寫(xiě)
滾動(dòng)經(jīng)典最新話題[prototype框架]下編寫(xiě)...2006-10-10初學(xué)prototype,發(fā)個(gè)JS接受URL參數(shù)的代碼
初學(xué)prototype,發(fā)個(gè)JS接受URL參數(shù)的代碼...2007-01-01Prototype源碼淺析 String部分(三)之HTML字符串處理
現(xiàn)在,String部分轉(zhuǎn)入具體的關(guān)聯(lián)應(yīng)用,分別對(duì)應(yīng)HTML字符串,JSON字符串和HTML中的腳本字符串2012-01-01Prototype Array對(duì)象 學(xué)習(xí)
這個(gè)對(duì)象擴(kuò)展了JS原生的Array對(duì)象,提供了一些基本的工具函數(shù),有些方法非常簡(jiǎn)單,源碼里就不在注釋了。2009-07-07Prototype Number對(duì)象 學(xué)習(xí)
這個(gè)對(duì)象提供一些操作數(shù)值類型的工具函數(shù)2009-07-07prototype Element學(xué)習(xí)筆記(篇二)
這一篇主要是要總論Element的所有函數(shù)。2008-10-10prototype Element學(xué)習(xí)筆記(篇一)
Element,哈哈哈。遇到正主了,到現(xiàn)在為止才遇到讓我高興的玩意。當(dāng)初Ext.Element可是花三千余行代碼專門(mén)來(lái)封裝啊。我倒要看一看它的代碼了。事實(shí)上prototype中我最想研究的只有兩個(gè)內(nèi)容:Element、Selector。這兩個(gè)東西是精華。2008-10-10Prototype 學(xué)習(xí) Prototype對(duì)象
Prototype 學(xué)習(xí) Prototype對(duì)象2009-07-07