1
+ <!DOCTYPE html>
2
+ < html >
3
+ < body >
4
+ < script type ="text/javascript ">
5
+ document . body . addEventListener ( 'click' , function ( ) {
6
+ alert ( 2 ) ;
7
+ } , false ) ;
8
+
9
+ document . body . click ( ) ; // 模拟用户点击
10
+
11
+ document . body . addEventListener ( 'click' , function ( ) {
12
+ alert ( 3 ) ;
13
+ } , false ) ;
14
+ document . body . addEventListener ( 'click' , function ( ) {
15
+ alert ( 4 ) ;
16
+ } , false ) ;
17
+ document . body . click ( ) ; // 模拟用户点击
18
+
19
+
20
+ var salesOffices = { } ; // 定义售楼处
21
+ salesOffices . clientList = [ ] ; // 缓存列表,存放订阅者的回调函数
22
+ salesOffices . listen = function ( fn ) { // 增加订阅者
23
+ this . clientList . push ( fn ) ; // 订阅的消息添加进缓存列表
24
+ } ;
25
+ salesOffices . trigger = function ( ) { // 发布消息
26
+ for ( var i = 0 , fn ; fn = this . clientList [ i ++ ] ; ) {
27
+ fn . apply ( this , arguments ) ; // arguments 是发布消息时带上的参数
28
+ }
29
+ } ;
30
+
31
+ //下面我们来进行一些简单的测试:
32
+ salesOffices . listen ( function ( price , squareMeter ) { // 小明订阅消息
33
+ console . log ( '价格= ' + price ) ;
34
+ console . log ( '价格= ' + price ) ;
35
+ console . log ( 'squareMeter = ' + squareMeter ) ;
36
+ } ) ;
37
+ salesOffices . trigger ( 2000000 , 88 ) ; // 输出:200 万,88 平方米
38
+ salesOffices . trigger ( 3000000 , 110 ) ; // 输出:300 万,110 平方米
39
+
40
+
41
+ var salesOffices1 = { } ; //定义售楼处
42
+ salesOffices1 . clientList = [ ] ; // 缓存列表,存放订阅者的回调函数
43
+
44
+ salesOffices1 . listen = function ( key , fn ) {
45
+ if ( ! this . clientList [ key ] ) { // 如果还没有订阅过此类消息,给该类消息创建一个缓存列表
46
+ this . clientList [ key ] = [ ] ;
47
+ }
48
+ this . clientList [ key ] . push ( fn ) ; // 订阅的消息添加进消息缓存列表
49
+ } ;
50
+
51
+ salesOffices1 . trigger = function ( ) { //发布消息
52
+ var key = Array . prototype . shift . call ( arguments ) , // 取出消息类型
53
+ fns = this . clientList [ key ] ; // 取出该消息对应的回调函数集合
54
+ if ( ! fns || fns . length === 0 ) {
55
+ return false ;
56
+ }
57
+ for ( var i = 0 , fn ; fn = fns [ i ++ ] ; ) {
58
+ fn . apply ( this , arguments ) ;
59
+ }
60
+ } ;
61
+
62
+ salesOffices1 . listen ( 'squareMeter88' , function ( price ) {
63
+ console . log ( '价格= ' + price ) ;
64
+ } ) ;
65
+ salesOffices1 . listen ( 'squareMeter110' , function ( price ) {
66
+ console . log ( '价格= ' + price ) ;
67
+ } ) ;
68
+
69
+ salesOffices1 . trigger ( 'squareMeter88' , 2000000 ) ;
70
+ salesOffices1 . trigger ( 'squareMeter110' , 3000000 ) ;
71
+
72
+
73
+ //所以我们把发布—订阅的功能提取出来,放在一个单独的对象内:
74
+ var event = {
75
+ clientList :[ ] ,
76
+ listen :function ( key , fn ) {
77
+ if ( ! this . clientList [ key ] ) {
78
+ this . clientList [ key ] = [ ] ;
79
+ }
80
+ this . clientList [ key ] . push ( fn ) ; // 订阅的消息添加进缓存列表
81
+ } ,
82
+ trigger :function ( ) {
83
+ var key = Array . prototype . shift . call ( arguments ) ,
84
+ fns = this . clientList [ key ] ;
85
+ if ( ! fns || fns . length === 0 ) { // 如果没有绑定对应的消息
86
+ return false ;
87
+ }
88
+ for ( var i = 0 , fn ; fn = fns [ i ++ ] ; ) {
89
+ fn . apply ( this . arguments ) ;
90
+ }
91
+ }
92
+ } ;
93
+
94
+ var installEvent = function ( obj ) {
95
+ for ( var i in event ) {
96
+ obj [ i ] = event [ i ] ;
97
+ }
98
+ } ;
99
+
100
+ //再来测试一番,我们给售楼处对象salesOffices 动态增加发布—订阅功能:
101
+ var salesOffices2 = { } ;
102
+ installEvent ( salesOffices2 ) ;
103
+ salesOffices2 . listen ( 'squareMeter88' , function ( price ) {
104
+ console . log ( '价格= ' + price ) ;
105
+ } ) ;
106
+ salesOffices2 . listen ( 'squareMeter100' , 3000000 ) ;
107
+ salesOffices2 . listen ( 'squareMeter88' , 2000000 ) ;
108
+
109
+
110
+ event . remove = function ( key , fn ) {
111
+ var fns = this . clientList [ key ] ;
112
+ if ( ! fns ) {
113
+ return false ; // 如果key 对应的消息没有被人订阅,则直接返回
114
+ }
115
+ if ( ! fn ) {
116
+ fns && ( fns . length = 0 ) ; // 如果没有传入具体的回调函数,表示需要取消key 对应消息的所有订阅
117
+ } else {
118
+ for ( var l = fns . length - 1 ; l >= 0 ; l -- ) { // 反向遍历订阅的回调函数列表
119
+ var _fn = fns [ l ] ;
120
+ if ( _fn === fn ) {
121
+ fns . splice ( l , 1 ) ; // 删除订阅者的回调函数
122
+ }
123
+ }
124
+ }
125
+ } ;
126
+
127
+ var salesOffices3 = { } ;
128
+ var installEvent = function ( obj ) {
129
+ for ( var i in event ) {
130
+ obj [ i ] = event [ i ] ;
131
+ }
132
+ }
133
+ installEvent ( salesOffices3 ) ;
134
+
135
+ salesOffices3 . listen ( 'squareMeter88' , fn1 = function ( price ) { // 小明订阅消息
136
+ console . log ( '价格= ' + price ) ;
137
+ } ) ;
138
+ salesOffices3 . listen ( 'squareMeter88' , fn2 = function ( price ) { // 小红订阅消息
139
+ console . log ( '价格= ' + price ) ;
140
+ } ) ;
141
+
142
+ salesOffices3 . remove ( 'squareMeter88' , fn1 ) ; // 删除小明的订阅
143
+ salesOffices3 . trigger ( 'squareMeter88' , 2000000 ) ; // 输出:2000000
144
+ </ script >
145
+ </ body >
146
+ </ html >
0 commit comments