1
+ /************ 模块定义 ************/
2
+
3
+ var Event = ( function ( ) {
4
+
5
+ var Event ,
6
+ _default = 'default' ; // 默认值
7
+ Event = ( function ( ) {
8
+ var _listen ,
9
+ _trigger ,
10
+ _remove ,
11
+ _shift = Array . prototype . shift ,
12
+ _unshift = Array . prototype . unshift ,
13
+ namespaceCache = { } ,
14
+ _create ,
15
+ each = function ( ary , fn ) {
16
+ var ret ;
17
+ for ( var i = 0 , l = ary . length ; i < l ; i ++ ) {
18
+ var n = ary [ i ] ;
19
+ ret = fn . call ( n , i , n ) ;
20
+ }
21
+ return ret ;
22
+ } ;
23
+
24
+ // 推入订阅的事件栈
25
+ _listen = function ( key , fn , cache ) {
26
+
27
+ // 无该事件的订阅则创建
28
+ if ( ! cache [ key ] ) {
29
+ cache [ key ] = [ ] ;
30
+ }
31
+
32
+ // 推入
33
+ cache [ key ] . push ( fn ) ;
34
+
35
+ //注意:cache是对象,对象参数是对象的一个引用,内部修改是会影响到外面的
36
+ } ;
37
+
38
+ // 移除订阅
39
+ _remove = function ( key , cache , fn ) {
40
+ if ( cache [ key ] ) {
41
+ /*
42
+ * 判断有无传函数
43
+ * 有:移除事件栈中的该函数
44
+ * 无:移除事件栈中所有的函数
45
+ * */
46
+ if ( fn ) {
47
+ for ( var i = cache [ key ] . length ; i >= 0 ; i -- ) {
48
+ if ( cache [ key ] === fn ) {
49
+ cache [ key ] . splice ( i , 1 ) ;
50
+ }
51
+ }
52
+ } else {
53
+ cache [ key ] = [ ] ;
54
+ }
55
+ }
56
+ } ;
57
+
58
+ // 发布订阅
59
+ _trigger = function ( ) {
60
+ var cache = _shift . call ( arguments ) , // 获取事件栈
61
+ key = _shift . call ( arguments ) , // 获取事件名
62
+ args = arguments , // 获取发布时的传参
63
+ _self = this , // 指向函数最后return出的对象,模块接口
64
+ stack = cache [ key ] ; // 事件栈中对应该事件名的所有函数
65
+
66
+ if ( ! stack || ! stack . length ) {
67
+ return ;
68
+ }
69
+
70
+
71
+ // 遍历事件栈中对应该事件名的所有函数,并在模块接口对象的环境下执行
72
+ return each ( stack , function ( ) {
73
+ return this . apply ( _self , args ) ;
74
+ } ) ;
75
+ } ;
76
+
77
+ // 传入事件的命名空间名,返回模块api
78
+ _create = function ( namespace ) {
79
+ var namespace = namespace || _default ;
80
+ var cache = { } ,
81
+ offlineStack = [ ] , // 存储已经发布的函数栈
82
+ ret = {
83
+ listen : function ( key , fn , last ) {
84
+ // 创建监听
85
+ _listen ( key , fn , cache ) ;
86
+
87
+ // 后面的逻辑都是处理先发布后订阅的离线事件,如果没有则直接return跳出
88
+ if ( offlineStack === null ) {
89
+ return ;
90
+ }
91
+
92
+ // 根据last是否为'last'决定是只拿最后一个函数,还是遍历执行所有已发布的函数
93
+ if ( last === 'last' ) {
94
+ offlineStack . length && offlineStack . pop ( ) ( ) ;
95
+ } else {
96
+ each ( offlineStack , function ( ) {
97
+ this ( ) ;
98
+ } ) ;
99
+ }
100
+
101
+ // 结束以后置空
102
+ offlineStack = null ;
103
+ } ,
104
+ one : function ( key , fn , last ) {
105
+
106
+ // 移除所有同名事件
107
+ _remove ( key , cache , fn ) ;
108
+
109
+ // 重新创建监听
110
+ this . listen ( key , fn , last ) ;
111
+ } ,
112
+ remove : function ( key , fn ) {
113
+ // 移除指定事件
114
+ _remove ( key , cache , fn ) ;
115
+ } ,
116
+ trigger : function ( ) {
117
+ var fn ,
118
+ args ,
119
+ _self = this ; // 指向模块返回api的对象
120
+
121
+ _unshift . call ( arguments , cache ) ; // 把订阅函数栈也添加到参数集合中,便于模块内部调用时获取
122
+ args = arguments ;
123
+
124
+ fn = function ( ) {
125
+ return _trigger . apply ( _self , args ) ;
126
+ } ;
127
+
128
+ // 如果offlineStack不为空,则把发布推入发布函数栈
129
+ if ( offlineStack ) {
130
+ return offlineStack . push ( fn ) ;
131
+ }
132
+ return fn ( ) ;
133
+ }
134
+ } ;
135
+
136
+ //判断是否传了命名空间,一般情况都为true,因为默认的命名空间是'default',是有值的
137
+ return namespace ? ( namespaceCache [ namespace ] ? namespaceCache [ namespace ] : namespaceCache [ namespace ] = ret ) : ret ;
138
+ } ;
139
+
140
+ return {
141
+ create : _create ,
142
+ one : function ( key , fn , last ) {
143
+ var event = this . create ( ) ;
144
+ event . one ( key , fn , last ) ;
145
+ } ,
146
+ remove : function ( key , fn ) {
147
+ var event = this . create ( ) ;
148
+ event . remove ( key , fn ) ;
149
+ } ,
150
+ listen : function ( key , fn , last ) {
151
+ var event = this . create ( ) ;
152
+ event . listen ( key , fn , last ) ;
153
+ } ,
154
+ trigger : function ( ) {
155
+ var event = this . create ( ) ;
156
+ event . trigger . apply ( this , arguments ) ;
157
+ }
158
+ }
159
+ } ( ) ) ;
160
+
161
+ return Event ;
162
+ } ( ) ) ;
163
+
164
+ /************ 先发布后订阅 ************/
165
+
166
+ Event . trigger ( 'click' , 5 ) ;
167
+ Event . trigger ( 'click' , 6 ) ;
168
+ Event . listen ( 'click' , function ( a ) {
169
+ console . log ( a ) ; // 输出:5
170
+ } ) ;
171
+
172
+ Event . listen ( 'click' , function ( a ) {
173
+ console . log ( a + 1 ) ; // 输出:5
174
+ } ) ;
175
+ Event . listen ( 'click' , function ( a ) {
176
+ console . log ( a + 2 ) ; // 输出:5
177
+ } ) ;
178
+ Event . trigger ( 'click' , 0 ) ;
179
+
180
+ console . log ( '*************************************' ) ;
181
+
182
+ /************ 使用命名空间 ************/
183
+
184
+ Event . create ( 'namespace1' ) . listen ( 'click' , function ( a ) {
185
+ console . log ( a ) ; // 输出:1
186
+ } ) ;
187
+ Event . create ( 'namespace1' ) . listen ( 'click' , function ( a ) {
188
+ console . log ( a + 1 ) ; // 输出:2
189
+ } ) ;
190
+
191
+ Event . create ( 'namespace1' ) . trigger ( 'click' , 1 ) ;
192
+
193
+ Event . create ( 'namespace2' ) . listen ( 'click' , function ( a ) {
194
+ console . log ( a ) ; // 输出:2
195
+ } ) ;
196
+
197
+ Event . create ( 'namespace2' ) . trigger ( 'click' , 20 ) ;
0 commit comments