分类:
2006-06-29 13:39:18
/** | |
2 | |
3 | * 定义一个全局对象, 属性 Version 在发布的时候会替换为当前版本号 |
4 | |
5 | */ |
6 | |
7 | var Prototype = { |
8 | |
9 | Version: '@@VERSION@@' |
10 | |
11 | } |
12 | |
13 | |
14 | /** |
15 | |
16 | * 创建一种类型,注意其属性 create 是一个方法,返回一个构造函数。 |
17 | |
18 | * 一般使用如下 |
19 | |
20 | * var X = Class.create(); 返回一个类型,类似于 java 的一个 |
21 | |
22 | * Class实例。 |
23 | |
24 | * 要使用 X 类型,需继续用 new X()来获取一个实例,如同 java 的 |
25 | |
26 | * Class.newInstance()方法。 |
27 | |
28 | * |
29 | |
30 | * 返回的构造函数会执行名为 initialize 的方法, initialize 是 |
31 | |
32 | * Ruby 对象的构造器方法名字。 |
33 | |
34 | * 此时initialize方法还没有定义,其后的代码中创建新类型时会建立 |
35 | |
36 | * 相应的同名方法。 |
37 | |
38 | * |
39 | |
40 | * 如果一定要从java上去理解。你可以理解为用Class.create()创建一个 |
41 | |
42 | * 继承java.lang.Class类的类。 |
43 | |
44 | * 当然java不允许这样做,因为Class类是final的 |
45 | |
46 | * |
47 | |
48 | */ |
49 | |
50 | var Class = { |
51 | |
52 | create: function() { |
53 | |
54 | return function() { |
55 | |
56 | this.initialize.apply(this, arguments); |
57 | |
58 | } |
59 | |
60 | } |
61 | |
62 | } |
63 | |
64 | |
65 | /** |
66 | |
67 | * 创建一个对象,从变量名来思考,本意也许是定义一个抽象类,以后创建 |
68 | |
69 | * 新对象都 extend 它。 |
70 | |
71 | * 但从其后代码的应用来看, Abstract 更多是为了保持命名空间清晰的考虑。 |
72 | |
73 | * 也就是说,我们可以给 Abstract 这个对象实例添加新的对象定义。 |
74 | |
75 | * |
76 | |
77 | * 从java去理解,就是动态给一个对象创建内部类。 |
78 | |
79 | */ |
80 | |
81 | var Abstract = new Object(); |
82 | |
83 | |
84 | /** |
85 | |
86 | * 获取参数对象的所有属性和方法,有点象多重继承。但是这种继承是动态获得的。 |
87 | |
88 | * 如: |
89 | |
90 | * var a = new ObjectA(), b = new ObjectB(); |
91 | |
92 | * var c = a.extend(b); |
93 | |
94 | * 此时 c 对象同时拥有 a 和 b 对象的属性和方法。但是与多重继承不同的是, |
95 | |
96 | * c instanceof ObjectB 将返回false。 |
97 | |
98 | */ |
99 | |
100 | Object.prototype.extend = function(object) { |
101 | |
102 | for (property in object) { |
103 | |
104 | this[property] = object[property]; |
105 | |
106 | } |
107 | |
108 | return this; |
109 | |
110 | } |
111 | |
112 | |
113 | /** |
114 | |
115 | * 这个方法很有趣,它封装一个javascript函数对象,返回一个新函数对象,新函 |
116 | |
117 | * 数对象的主体和原对象相同,但是bind()方法参数将被用作当前对象的对象。 |
118 | |
119 | * 也就是说新函数中的 this 引用被改变为参数提供的对象。 |
120 | |
121 | * 比如: |
122 | |
123 | * |
124 | |
125 | * |
126 | |
127 | * ................. |
128 | |
129 | * |
140 | |
141 | * 那么,调用aaa.showValue 将返回"aaa", |
142 | |
143 | * 但调用aaa.showValue2 将返回"bbb"。 |
144 | |
145 | * |
146 | |
147 | * apply 是ie5.5后才出现的新方法(Netscape好像很早就支持了)。 |
148 | |
149 | * 该方法更多的资料参考MSDN |
150 | |
151 | * |
152 | |
153 | * 还有一个 call 方法,应用起来和 apply 类似。可以一起研究下。 |
154 | |
155 | */ |
156 | |
157 | Function.prototype.bind = function(object) { |
158 | |
159 | var method = this; |
160 | |
161 | return function() { |
162 | |
163 | method.apply(object, arguments); |
164 | |
165 | } |
166 | |
167 | } |
168 | |
169 | |
170 | /** |
171 | |
172 | * 和bind一样,不过这个方法一般用做html控件对象的事件处理。所以要传递event对象 |
173 | |
174 | * 注意这时候,用到了 Function.call。它与 Function.apply 的不同好像仅仅是对参 |
175 | |
176 | * 数形式的定义。如同 java 两个过载的方法。 |
177 | |
178 | */ |
179 | |
180 | Function.prototype.bindAsEventListener = function(object) { |
181 | |
182 | var method = this; |
183 | |
184 | return function(event) { |
185 | |
186 | method.call(object, event || window.event); |
187 | |
188 | } |
189 | |
190 | } |
191 | |
192 | |
193 | /** |
194 | |
195 | * 将整数形式RGB颜色值转换为HEX形式 |
196 | |
197 | */ |
198 | |
199 | Number.prototype.toColorPart = function() { |
200 | |
201 | var digits = this.toString(16); |
202 | |
203 | if (this < 16) return '0' + digits; |
204 | |
205 | return digits; |
206 | |
207 | } |
208 | |
209 | |
210 | /** |
211 | |
212 | * 典型 Ruby 风格的函数,将参数中的方法逐个调用,返回第一个成功执行的方法的返回值 |
213 | |
214 | */ |
215 | |
216 | var Try = { |
217 | |
218 | these: function() { |
219 | |
220 | var returnValue; |
221 | |
222 | |
223 | for (var i = 0; i < arguments.length; i++) { |
224 | |
225 | var lambda = arguments[i]; |
226 | |
227 | try { |
228 | |
229 | returnValue = lambda(); |
230 | |
231 | break; |
232 | |
233 | } catch (e) {} |
234 | |
235 | } |
236 | |
237 | |
238 | return returnValue; |
239 | |
240 | } |
241 | |
242 | } |
243 | |
244 | |
245 | /*--------------------------------------------------------------------------*/ |
246 | |
247 | |
248 | /** |
249 | |
250 | * 一个设计精巧的定时执行器 |
251 | |
252 | * 首先由 Class.create() 创建一个 PeriodicalExecuter 类型, |
253 | |
254 | * 然后用对象直接量的语法形式设置原型。 |
255 | |
256 | * |
257 | |
258 | * 需要特别说明的是 rgisterCallback 方法,它调用上面定义的函数原型方法bind, |
259 | |
260 | * 并传递自己为参数。 |
261 | |
262 | * 之所以这样做,是因为 setTimeout 默认总以 window 对象为当前对象,也就是说, |
263 | |
264 | * 如果 registerCallback 方法定义如下的话: |
265 | |
266 | * registerCallback: function() { |
267 | |
268 | * setTimeout(this.onTimerEvent, this.frequency * 1000); |
269 | |
270 | * } |
271 | |
272 | * 那么,this.onTimeoutEvent 方法执行失败,因为它无法 |
273 | |
274 | * 访问 this.currentlyExecuting 属性。 |
275 | |
276 | * 而使用了bind以后,该方法才能正确的找到this, |
277 | |
278 | * 也就是PeriodicalExecuter的当前实例。 |
279 | |
280 | */ |
281 | |
282 | var PeriodicalExecuter = Class.create(); |
283 | |
284 | PeriodicalExecuter.prototype = { |
285 | |
286 | initialize: function(callback, frequency) { |
287 | |
288 | this.callback = callback; |
289 | |
290 | this.frequency = frequency; |
291 | |
292 | this.currentlyExecuting = false; |
293 | |
294 | |
295 | this.registerCallback(); |
296 | |
297 | }, |
298 | |
299 | |
300 | registerCallback: function() { |
301 | |
302 | setTimeout(this.onTimerEvent.bind(this), this.frequency * 1000); |
303 | |
304 | }, |
305 | |
306 | |
307 | onTimerEvent: function() { |
308 | |
309 | if (!this.currentlyExecuting) { |
310 | |
311 | try { |
312 | |
313 | this.currentlyExecuting = true; |
314 | |
315 | this.callback(); |
316 | |
317 | } finally { |
318 | |
319 | this.currentlyExecuting = false; |
320 | |
321 | } |
322 | |
323 | } |
324 | |
325 | |
326 | this.registerCallback(); |
327 | |
328 | } |
329 | |
330 | } |
331 | |
332 | |
333 | /*--------------------------------------------------------------------------*/ |
334 | |
335 | |
336 | /** |
337 | |
338 | * 这个函数就 Ruby 了。我觉得它的作用主要有两个 |
339 | |
340 | * 1. 大概是 document.getElementById(id) 的最简化调用。 |
341 | |
342 | * 比如:$("aaa") 将返回上 aaa 对象 |
343 | |
344 | * 2. 得到对象数组 |
345 | |
346 | * 比如: $("aaa","bbb") 返回一个包括id为 |
347 | |
348 | * "aaa"和"bbb"两个input控件对象的数组。 |
349 | |
350 | */ |
351 | |
352 | function $() { |
353 | |
354 | var elements = new Array(); |
355 | |
356 | |
357 | for (var i = 0; i < arguments.length; i++) { |
358 | |
359 | var element = arguments[i]; |
360 | |
361 | if (typeof element == 'string') |
362 | |
363 | element = document.getElementById(element); |
364 | |
365 | |
366 | if (arguments.length == 1) |
367 | |
368 | return element; |
369 | |
370 | |
371 | elements.push(element); |
372 | |
373 | } |
374 | |
375 | |
376 | return elements; |
377 | |
378 | } |
379 |