首页 > 网站 > WEB开发 > 正文

Backbone Events 源码笔记

2024-04-27 14:21:55
字体:
来源:转载
供稿:网友

Backbone Events 源码笔记

用了backbone一段时间了,做一些笔记和总结,看的源码是1.12

backbone有events,model,collection,histoty,router,view这些模块,其中events是最基础的,其他的模块的PRototype全部都扩展了他,所以events是非常重要的,真的很重要,还好代码比较简单,也比较好理解

这个里面的代码是从backbone里面剥离出来,然后一点一点研究和调试出来的,可以单独运行,依赖underscore

  1     (function(){  2         this.Backbone = {};  3         var array = [];  4         var slice = array.slice;  5         // Regular expression used to split event strings.  6         //劈开eventsApi函数里面传入name,如果name是带空格的字符串  7         var eventSplitter = //s+/;  8   9   // Implement fancy features of the Events API such as multiple event 10   // names `"change blur"` and jQuery-style event maps `{change: action}` 11   // in terms of the existing API. 12         //如果传入的name(这个对应绑定 删除 触发 监听的事件名)为obj 或者是带空格的字符串,则批量进行相关的操作 13         var eventsApi = function(obj, action, name, rest) { 14             if (!name) return true; 15  16             // Handle event maps. 17             if (typeof name === 'object') { 18                 for (var key in name) { 19                     obj[action].apply(obj, [key, name[key]].concat(rest)); 20                 } 21                 return false; 22             } 23  24             // Handle space separated event names. 25             if (eventSplitter.test(name)) { 26                 var names = name.split(eventSplitter); 27                 for (var i = 0, length = names.length; i < length; i++) { 28                     obj[action].apply(obj, [names[i]].concat(rest)); 29                 } 30                 return false; 31             } 32  33             return true; 34         }; 35  36  37  38         var Events = Backbone.Events = { 39             // Bind an event to a `callback` function. Passing `"all"` will bind 40             // the callback to all events fired. 41             // 参数的传入为  事件名, 回调, 回调里面this指向的对象 42             on: function(name, callback, context) { 43                 if (!eventsApi(this, 'on', name, [callback, context]) || !callback) return this; 44                 //对象内部生成一个_events对象 key对应事件名, value为一个数组,里面添加相关的回调函数 45                 this._events || (this._events = {}); 46                 var events = this._events[name] || (this._events[name] = []); 47                 //第3个和第4个参数,表示回调函数触发的是偶, 函数里面this的指向 48                 events.push({callback: callback, context: context, ctx: context || this}); 49                 return this; 50             }, 51             // Bind an event to only be triggered a single time. After the first time 52             // the callback is invoked, it will be removed. 53             //  跟on一样的入参 ,他只会执行一次 54             once: function(name, callback, context) { 55                 if (!eventsApi(this, 'once', name, [callback, context]) || !callback) return this; 56                 var self = this; 57                 //真正绑定进_.events的事故once 而不是callback,当once执行完一次后,就从_events上面删除掉了 58                 var once = _.once(function() { 59                     self.off(name, once); 60                     callback.apply(this, arguments); 61                 }); 62                 once._callback = callback; 63                 return this.on(name, once, context); 64             }, 65  66             // Trigger one or many events, firing all bound callbacks. Callbacks are 67             // passed the same arguments as `trigger` is, apart from the event name 68             // (unless you're listening on `"all"`, which will cause your callback to 69             // receive the true name of the event as the first argument). 70             trigger: function(name) { 71                 if (!this._events) return this; 72                 var args = slice.call(arguments, 1); 73                 if (!eventsApi(this, 'trigger', name, args)) return this; 74                 var events = this._events[name]; 75                 var allEvents = this._events.all; 76                 //通过name 找到对应的回调数组  依次执行里面的回调 77                 if (events) triggerEvents(events, args); 78                 //查看是否绑定了all事件 如果绑定也会出阿发 79                 if (allEvents) triggerEvents(allEvents, arguments); 80                 return this; 81             }, 82  83             // Remove one or many callbacks. If `context` is null, removes all 84             // callbacks with that function. If `callback` is null, removes all 85             // callbacks for the event. If `name` is null, removes all bound 86             // callbacks for all events. 87             off: function(name, callback, context) { 88                 if (!this._events || !eventsApi(this, 'off', name, [callback, context])) return this; 89  90                 // Remove all callbacks for all events. 91                 //如果参数不存在 就移除所有的事件 92                 if (!name && !callback && !context) { 93                     this._events = void 0; 94                     return this; 95                 } 96  97                 var names = name ? [name] : _.keys(this._events); 98                 for (var i = 0, length = names.length; i < length; i++) { 99                     name = names[i];100 101                     // Bail out if there are no events stored.102                     var events = this._events[name];103                     if (!events) continue;104 105                     // Remove all callbacks for this event.106                     //如果只传递name这一个参数 就删除name对应的整个数组107                     if (!callback && !context) {108                         delete this._events[name];109                         continue;110                     }111 112                     // Find any remaining events.113                     //114                     //如果如果传递了第2个参数  只删除_events[name]里面对应的callback115                     //如果传递了第2个参数,第3个参数,还要判断_events[name]里面的callback是否等于第2个参数,context是否等于第3个参数116                     //把那么不符合条件的用remaining保存起来117                     //然后用this._events[name] = remaining替换掉之前的118                     var remaining = [];119                     for (var j = 0, k = events.length; j < k; j++) {120                         var event = events[j];121                         if (122                             callback && callback !== event.callback &&123                             callback !== event.callback._callback ||124                             context && context !== event.context125                         ) {126                             remaining.push(event);127                         }128                     }129 130                     // Replace events if there are any remaining.  Otherwise, clean up.131                     if (remaining.length) {132                         this._events[name] = remaining;133                     } else {134                         delete this._events[name];135                     }136                 }137 138               return this;139             },140             // Tell this object to stop listening to either specific events ... or141             // to every object it's currently listening to.142             stopListening: function(obj, name, callback) {143                 var listeningTo = this._listeningTo;144                 if (!listeningTo) return this;145                 var remove = !name && !callback;146                 if (!callback && typeof name === 'object') callback = this;147                 if (obj) (listeningTo = {})[obj._listenId] = obj;148                 for (var id in listeningTo) {149                     obj = listeningTo[id];150                     obj.off(name, callback, this);151                     if (remove || _.isEmpty(obj._events)) delete this._listeningTo[id];152                 }153                 return this;154             }            155         }156 157         var listenMethods = {listenTo: 'on', listenToOnce:
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表