码迷,mamicode.com
首页 > Web开发 > 详细

JQuery源码解析--callbacks

时间:2016-08-14 22:09:20      阅读:200      评论:0      收藏:0      [点我收藏+]

标签:

  1 (function (global, factory) {
  2     factory(global);
  3 })(this, function (window, noGlobal) {
  4     var rootjQuery;
  5     var class2type = {};
  6     var toString = class2type.toString;
  7     var arr = [];
  8     var indexOf = arr.indexOf;
  9     var myJQuery = function (selector, context) {
 10         return new myJQuery.fn.init(selector, context);
 11     };
 12 
 13     myJQuery.fn = myJQuery.prototype = {
 14         constructor: myJQuery,//为撒指定
 15         length: 0,
 16         each: function (callback) {
 17             return myJQuery.each(this, callback);
 18         },
 19         pushStack: function (elems) {
 20             var ret = myJQuery.merge(this.constructor(), elems);
 21             ret.prevObject = this;
 22             ret.context = this.context;
 23             return ret;
 24         }
 25     };
 26 
 27     myJQuery.extend = myJQuery.fn.extend = function () {
 28         var options, name, src, copy, target = arguments[0] || {}, length = arguments.length, i = 1;
 29         if (i === length) {
 30             target = this;
 31             i--;
 32         }
 33         for (; i < length; i++) {
 34             if ((options = arguments[i]) != null) {
 35                 for (name in options) {
 36                     src = target[name];
 37                     copy = options[name];
 38                     if (target === copy) {
 39                         continue;
 40                     }
 41 
 42                     if (copy !== undefined) {
 43                         target[name] = copy;
 44                     }
 45                 }
 46             }
 47         }
 48         return target;
 49     };
 50 
 51     function isArrayLike(obj) {
 52         var length = !!obj && "length" in obj && obj.length,
 53             type = myJQuery.type(obj);
 54         if (type === "function" || myJQuery.isWindow(obj)) {
 55             return false;
 56         }
 57 
 58         return type === "array" || length === 0 ||
 59             typeof length === "number" && length > 0 && ( length - 1 ) in obj;
 60     }
 61 
 62     myJQuery.extend({
 63         isWindow: function( obj ) {
 64             return obj != null && obj === obj.window;
 65         },
 66         //extend each,是一种静态方法 调用方式 myJQuery.each(.....)
 67         each: function (obj, callback) {
 68             var length, i = 0;
 69             if (isArrayLike(obj)) {
 70                 //如果是数组
 71                 length = obj.length;//设置的属性
 72                 for (; i < length; i++) {
 73                     if (callback.call(obj[i], i, obj[i]) === false) {
 74                         break;
 75                     }
 76                 }
 77             }
 78             else{
 79                 //如果是对象
 80                 for(i in obj){
 81                     if(callback.call(obj[i],i,obj[i])===false){
 82                         break;
 83                     }
 84                 }
 85             }
 86             return obj;
 87         },
 88         isFunction: function (obj) {
 89             return myJQuery.type(obj) === "function";
 90         },
 91         type: function (obj) {
 92             if (obj == null) {
 93                 return obj + "";
 94             }
 95 
 96             // Support: Android<4.0, iOS<6 (functionish RegExp)
 97             /*return typeof obj === "object" || typeof obj === "function" ?
 98              class2type[toString.call(obj)] || "object" :
 99              typeof obj;*/
100             return typeof obj;
101         },
102         merge: function (first, second) {
103             var len = +second.length,
104                 j = 0,
105                 i = first.length;
106             for (; j < len; j++) {
107                 first[i++] = second[j];
108             }
109             first.length = i;
110             return first;
111         },
112         inArray: function (elem, arr, i) {
113             return arr == null ? -1 : indexOf.call(arr, elem, i);
114         }
115     });
116 
117     myJQuery.fn.extend({
118         find: function (selector) {
119             var ret = [];
120             var arr = [12, 35, 68];
121             ret = this.pushStack(arr);
122             ret.selector = selector;
123             return ret;
124         }
125     });
126 
127     var rnotwhite = (/\S+/g); //大s 非空白字符 小s 空白字符
128     ///g 表示该表达式将用来在输入字符串中查找所有可能的匹配,返回的结果可以是多个。如果不加/g最多只会匹配一个
129 
130     function createOptions(options) {
131         var object = {};
132         //match 匹配成功,返回数组,否则 返回null
133         myJQuery.each(options.match(rnotwhite) || [], function (_, flag) {
134             object[flag] = true;
135         });
136         return object;
137     }
138 
139     myJQuery.Callbacks = function (options) {
140         options = typeof  options === "string" ? createOptions(options) : myJQuery.extend({}, options);
141         var firing, memory, fired, locked, list = [], queue = [], firingIndex = -1;
142         var fire = function () {
143             locked = options.once;
144             for (; queue.length; firingIndex = -1) {
145                 memory = queue.shift();
146                 while (++firingIndex < list.length) {
147                     if(list[firingIndex].apply(memory[0], memory[1])===false && options.stopOnFalse===true){
148                         firingIndex=list.length;
149                         memory = false; //预防 参数里有 memory
150                     }
151                 }
152             }
153 
154             //memory是一个全局变量,一直存在,而在add的时候,又有
155             // if(memory && !firing){ fire(); }
156             if(!options.memory){
157                 memory=false;
158             }
159 
160             if (locked) {
161                 if (memory) {
162                     list=[];
163                 } else {
164                     list = "";
165                 }
166             }
167         };
168         var self = {
169             add: function () {
170                 if (list) {
171                     if (memory && !firing) {
172                         firingIndex = list.length - 1;
173                         queue.push(memory);
174                     }
175 
176                     (function addSelf(args) {
177                         myJQuery.each(args, function (_, arg) {
178                             if (myJQuery.isFunction(arg)) {
179                                 if (!options.unique || !self.has(arg)) {
180                                     list.push(arg);
181                                 }
182                             } else if (arg && arg.length && myJQuery.type(arg) !== "string") {
183                                 //适用于 add([fn1,fn2]);
184                                 addSelf(arg);
185                             }
186                         });
187                     })(arguments);
188 
189                     if(memory && !firing){
190                         //传入 memory关键字,在add的时候,将之前所有的fn fire 一次
191                         fire();
192                     }
193                     return this;
194                 }
195             },
196             remove: function () {
197                 myJQuery.each(arguments, function (_, arg) {
198                     var index = 0;
199                     while ((index = myJQuery.inArray(arg, list, index)) > -1) {
200                         list.splice(index, 1);
201                     }
202                 });
203                 return this;
204             },
205             has: function (fn) {
206                 return fn ? myJQuery.inArray(fn, list) > -1 : list.length > 0;
207             },
208             empty: function () {
209                 if (list) {
210                     list = [];
211                 }
212                 return this;
213             },
214             disable: function () {
215 
216             },
217             disabled: function () {
218 
219             },
220             lock: function () {
221 
222             },
223             locked: function () {
224 
225             },
226             fireWith: function (context, args) {
227                 //when options.once=true,the locked=true,and not fired
228                 if (!locked) {
229                     args = args || [];
230                     queue.push([context, args]);
231                     fire();
232                 }
233                 return this;
234             },
235             fire: function () {
236                 self.fireWith(this, arguments);
237                 return this;
238             },
239             fired: function () {
240 
241             }
242         };
243         return self;
244     }
245     var init = myJQuery.fn.init = function (selector, context, root) {
246         if (!selector) {
247             return this;
248         }
249         root = root || rootjQuery;
250         //处理标签 div p li
251         if (typeof selector === "string") {
252             return ( context || root ).find(selector);
253         } else if (selector.nodeType) {
254             this.context = this[0] = selector;
255             this.length = 1;
256             return this;
257         }
258     };
259 
260     init.prototype = myJQuery.fn;
261 
262     rootjQuery = myJQuery(document);
263 
264     if (!noGlobal) {
265         window.myJQuery = window.F$ = myJQuery;
266     }
267 
268     return myJQuery;
269 });

 

JQuery源码解析--callbacks

标签:

原文地址:http://www.cnblogs.com/xianrongbin/p/5770969.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!