Pro javascript design pattern 读书笔记之 The structure of a chain
2008-10-29 14:18 wlstyle 阅读(222) 评论(0) 收藏 举报Chaining
在这章中我们将关注javascript的chain methods together.通过使用一些简单的技术,开发者能很优雅的写代码(就向jquery中)。为通常的任务节省了很多的时间,你能改进代码的实现方式。最后你能写一个包含chaining所有技术的javascript库。Chains所有你喜欢的代码在一块。
Chaining 只是一个语法上的hack.它允许你通过减少初始化操作从而在一些代码中体验复杂的操作。Chaining需要两个部分:一个在html元素中创建对象的工厂,和一些使用这些html元素执行操作的方法。每一个方法都能通过在方法名后加入一个点号加入到链中。链相当于一个在页面中选择元素然后对这个元素执行多个操作。
让我们看一些例子。使用一些内置的函数,你能通过观察”before and after”的对比来了解chainning的基本概念。在这个例子中内置函数是如果工作的并不重要,这是第一个通过一个id对一个元素进行引用然后给他分配一个事件监听函数。当单击的时候,他设置文本的颜色为绿色,然后显示这个元素。
2
3 addevent($('example'),'click',function(){
4
5 setStyle(this,'color','green');
6
7 show(this);
8
9 })
10
11 //with chaining
12
13 $('example').addevent('click',function(){
14
15 $(this).setStyle('color','green').show();
16
17 })
18
The structure of a chain
你已经对$这个函数很熟悉了。通常返回一个html元素或者html元素的集合。$函数如下:
2
3 var elements=[];
4
5 for(var i=0,len=arguments.length;i<len;i++){
6
7 var element=arguments[i];
8
9 if (typeof element ==="string"){
10
11 element= document.getElementById(element);
12
13 }
14
15 if(arguments.length === 1){
16
17 return element;
18
19 }
20
21 elements.push(element);
22
23
24
25 }
26
27 return elements;
28
29
30
31 }
32
33
然而,如果你改变这个函数,让他作为一个构造函数,存储这些元素作为一个实例的属性,然后在原型方法中返回一个对实例的引用,你就能给予它chain的能力。你需要改变$函数以便他成为一个工厂方法。创建一个支持chaining的对象.你同样希望$函数能有一个包含元素的数组,所以你能使用同样的公有接口。改造后的代码如下:
2
3 //use a private class
4
5 function _$(els){
6
7 this.elements=[];
8
9 for(var i=0,len=els.length;i<len;i++){
10
11 var element=els[i];
12
13 if(typeof element === "string"){
14
15 element=document.getElementById(element);
16
17 }
18
19 this.elements.push(element);
20
21 }
22
23 }
24
25 //the public interface
26
27 window.$=function(){
28
29 return new _$(els)
30
31 }
32
33 })()
34
因为所有的对象通过原型实现继承,你能使用被返回实例对象的引用调用每一个作为原型链的方法。通过这中思想。我们继续改造这个函数,通过在$中添加构造函数属性。这样就使链成为一种可能。
2
3 //use a private class
4
5 function _$(els){
6
7 this.elements=[];
8
9 for(var i=0,len=els.length;i<len;i++){
10
11 var element=els[i];
12
13 if(typeof element === "string"){
14
15 element=document.getElementById(element);
16
17 }
18
19 this.elements.push(element);
20
21 }
22
23 }
24
25 _$.prototype={
26
27 each: function(fn){
28
29 for(var i=0,len= this.elements.length;i<len;i++){
30
31 fn.call(this,this.elements[i]);
32
33 }
34
35 return this;
36
37 },
38
39 setStyle:function(prop,val){
40
41 this.each(function(el){
42
43 el.style[prop]=val;
44
45 });
46
47 return this;
48
49 },
50
51 show:function(){
52
53 var that=this;
54
55 this.each(function(el){
56
57 that.setStyle('display','block');
58
59 });
60
61 return this;
62
63
64
65 },
66
67 addEvent:function(type,fn){
68
69 var add=function(el){
70
71 if(window.addEventListener){
72
73 el.addEventListener(type,fn,false);
74
75 }else if(window.attachEvent){
76
77 el.attachEvent('on'+type,fn);
78
79
80
81 }
82
83 };
84
85 this.each(function(el){
86
87 add(el)
88
89 });
90
91 return this;
92
93 }
94
95
96
97 };
98
99 //the public interface
100
101 window.$=function(){
102
103 return new _$(els)
104
105 }
106
107 })()
108
109
如果你检查每个方法的最后一行,你会注意到他们都是以return this 结束。这个可以在方法之间传递对象。有了链的接口。你就以下面这种方式写代码了。
2
3 $('test-1','test-2').show().
4
5 setStyle('color','red').
6
7 addEvent('click',function(e){
8
9 $(this).setStyle('color','green');
10
11 });
12
13 })
14
这样就为window对象在加载的时候绑定了一个事件,id为test-1和test-2的元素立即显示。他们内部的元素将被设置为红色。他们然后绑定了一个事件监听函数。当这个函数执行的时候将设置文字的颜色为绿色。
这种写法和jquery这个库很类似。这个接口也很接近。链的锚点是window对象或者是html元素。每一个操作都以锚点为中心。在上面是例子中,有两个链。一个是对于window对象的加载事件。另外是id为thes-1和test-2元素设置样式的事件。我们将在下一部分深入这种模式。
浙公网安备 33010602011771号