forked from leancloud/javascript-sdk
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathevent.js
More file actions
158 lines (144 loc) · 4.64 KB
/
Copy pathevent.js
File metadata and controls
158 lines (144 loc) · 4.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
/**
* 每位工程师都有保持代码优雅的义务
* Each engineer has a duty to keep the code elegant
**/
/*global _: false */
module.exports = function(AV) {
var eventSplitter = /\s+/;
var slice = Array.prototype.slice;
/**
* @class
*
* <p>AV.Events is a fork of Backbone's Events module, provided for your
* convenience.</p>
*
* <p>A module that can be mixed in to any object in order to provide
* it with custom events. You may bind callback functions to an event
* with `on`, or remove these functions with `off`.
* Triggering an event fires all callbacks in the order that `on` was
* called.
*
* <pre>
* var object = {};
* _.extend(object, AV.Events);
* object.on('expand', function(){ alert('expanded'); });
* object.trigger('expand');</pre></p>
*
* <p>For more information, see the
* <a href="http://documentcloud.github.com/backbone/#Events">Backbone
* documentation</a>.</p>
*/
AV.Events = {
/**
* Bind one or more space separated events, `events`, to a `callback`
* function. Passing `"all"` will bind the callback to all events fired.
*/
on: function(events, callback, context) {
var calls, event, node, tail, list;
if (!callback) {
return this;
}
events = events.split(eventSplitter);
calls = this._callbacks || (this._callbacks = {});
// Create an immutable callback list, allowing traversal during
// modification. The tail is an empty object that will always be used
// as the next node.
event = events.shift();
while (event) {
list = calls[event];
node = list ? list.tail : {};
node.next = tail = {};
node.context = context;
node.callback = callback;
calls[event] = {tail: tail, next: list ? list.next : node};
event = events.shift();
}
return this;
},
/**
* Remove one or many callbacks. If `context` is null, removes all callbacks
* with that function. If `callback` is null, removes all callbacks for the
* event. If `events` is null, removes all bound callbacks for all events.
*/
off: function(events, callback, context) {
var event, calls, node, tail, cb, ctx;
// No events, or removing *all* events.
if (!(calls = this._callbacks)) {
return;
}
if (!(events || callback || context)) {
delete this._callbacks;
return this;
}
// Loop through the listed events and contexts, splicing them out of the
// linked list of callbacks if appropriate.
events = events ? events.split(eventSplitter) : _.keys(calls);
event = events.shift();
while (event) {
node = calls[event];
delete calls[event];
if (!node || !(callback || context)) {
continue;
}
// Create a new list, omitting the indicated callbacks.
tail = node.tail;
node = node.next;
while (node !== tail) {
cb = node.callback;
ctx = node.context;
if ((callback && cb !== callback) || (context && ctx !== context)) {
this.on(event, cb, ctx);
}
node = node.next;
}
event = events.shift();
}
return this;
},
/**
* Trigger one or many events, firing all bound callbacks. Callbacks are
* passed the same arguments as `trigger` is, apart from the event name
* (unless you're listening on `"all"`, which will cause your callback to
* receive the true name of the event as the first argument).
*/
trigger: function(events) {
var event, node, calls, tail, args, all, rest;
if (!(calls = this._callbacks)) {
return this;
}
all = calls.all;
events = events.split(eventSplitter);
rest = slice.call(arguments, 1);
// For each event, walk through the linked list of callbacks twice,
// first to trigger the event, then to trigger any `"all"` callbacks.
event = events.shift();
while (event) {
node = calls[event];
if (node) {
tail = node.tail;
while ((node = node.next) !== tail) {
node.callback.apply(node.context || this, rest);
}
}
node = all;
if (node) {
tail = node.tail;
args = [event].concat(rest);
while ((node = node.next) !== tail) {
node.callback.apply(node.context || this, args);
}
}
event = events.shift();
}
return this;
}
};
/**
* @function
*/
AV.Events.bind = AV.Events.on;
/**
* @function
*/
AV.Events.unbind = AV.Events.off;
};