JQuery源码解析--callbacks
(function (global, factory) { factory(global); })(this, function (window, noGlobal) { var rootjQuery; var class2type = {}; var toString = class2type.toString; var arr = []; var indexOf = arr.indexOf; var myJQuery = function (selector, context) { return new myJQuery.fn.init(selector, context); }; myJQuery.fn = myJQuery.prototype = { constructor: myJQuery,//为撒指定 length: 0, each: function (callback) { return myJQuery.each(this, callback); }, pushStack: function (elems) { var ret = myJQuery.merge(this.constructor(), elems); ret.prevObject = this; ret.context = this.context; return ret; } }; myJQuery.extend = myJQuery.fn.extend = function () { var options, name, src, copy, target = arguments[0] || {}, length = arguments.length, i = 1; if (i === length) { target = this; i--; } for (; i < length; i++) { if ((options = arguments[i]) != null) { for (name in options) { src = target[name]; copy = options[name]; if (target === copy) { continue; } if (copy !== undefined) { target[name] = copy; } } } } return target; }; function isArrayLike(obj) { var length = !!obj && "length" in obj && obj.length, type = myJQuery.type(obj); if (type === "function" || myJQuery.isWindow(obj)) { return false; } return type === "array" || length === 0 || typeof length === "number" && length > 0 && ( length - 1 ) in obj; } myJQuery.extend({ isWindow: function( obj ) { return obj != null && obj === obj.window; }, //extend each,是一种静态方法 调用方式 myJQuery.each(.....) each: function (obj, callback) { var length, i = 0; if (isArrayLike(obj)) { //如果是数组 length = obj.length;//设置的属性 for (; i < length; i++) { if (callback.call(obj[i], i, obj[i]) === false) { break; } } } else{ //如果是对象 for(i in obj){ if(callback.call(obj[i],i,obj[i])===false){ break; } } } return obj; }, isFunction: function (obj) { return myJQuery.type(obj) === "function"; }, type: function (obj) { if (obj == null) { return obj + ""; } // Support: Android<4.0, iOS<6 (functionish RegExp) /*return typeof obj === "object" || typeof obj === "function" ? class2type[toString.call(obj)] || "object" : typeof obj;*/ return typeof obj; }, merge: function (first, second) { var len = +second.length, j = 0, i = first.length; for (; j < len; j++) { first[i++] = second[j]; } first.length = i; return first; }, inArray: function (elem, arr, i) { return arr == null ? -1 : indexOf.call(arr, elem, i); } }); myJQuery.fn.extend({ find: function (selector) { var ret = []; var arr = [12, 35, 68]; ret = this.pushStack(arr); ret.selector = selector; return ret; } }); var rnotwhite = (/\S+/g); //大s 非空白字符 小s 空白字符 ///g 表示该表达式将用来在输入字符串中查找所有可能的匹配,返回的结果可以是多个。如果不加/g最多只会匹配一个 function createOptions(options) { var object = {}; //match 匹配成功,返回数组,否则 返回null myJQuery.each(options.match(rnotwhite) || [], function (_, flag) { object[flag] = true; }); return object; } myJQuery.Callbacks = function (options) { options = typeof options === "string" ? createOptions(options) : myJQuery.extend({}, options); var firing, memory, fired, locked, list = [], queue = [], firingIndex = -1; var fire = function () { locked = options.once; for (; queue.length; firingIndex = -1) { memory = queue.shift(); while (++firingIndex < list.length) { if(list[firingIndex].apply(memory[0], memory[1])===false && options.stopOnFalse===true){ firingIndex=list.length; memory = false; //预防 参数里有 memory } } } //memory是一个全局变量,一直存在,而在add的时候,又有 // if(memory && !firing){ fire(); } if(!options.memory){ memory=false; } if (locked) { if (memory) { list=[]; } else { list = ""; } } }; var self = { add: function () { if (list) { if (memory && !firing) { firingIndex = list.length - 1; queue.push(memory); } (function addSelf(args) { myJQuery.each(args, function (_, arg) { if (myJQuery.isFunction(arg)) { if (!options.unique || !self.has(arg)) { list.push(arg); } } else if (arg && arg.length && myJQuery.type(arg) !== "string") { //适用于 add([fn1,fn2]); addSelf(arg); } }); })(arguments); if(memory && !firing){ //传入 memory关键字,在add的时候,将之前所有的fn fire 一次 fire(); } return this; } }, remove: function () { myJQuery.each(arguments, function (_, arg) { var index = 0; while ((index = myJQuery.inArray(arg, list, index)) > -1) { list.splice(index, 1); } }); return this; }, has: function (fn) { return fn ? myJQuery.inArray(fn, list) > -1 : list.length > 0; }, empty: function () { if (list) { list = []; } return this; }, disable: function () { }, disabled: function () { }, lock: function () { }, locked: function () { }, fireWith: function (context, args) { //when options.once=true,the locked=true,and not fired if (!locked) { args = args || []; queue.push([context, args]); fire(); } return this; }, fire: function () { self.fireWith(this, arguments); return this; }, fired: function () { } }; return self; } var init = myJQuery.fn.init = function (selector, context, root) { if (!selector) { return this; } root = root || rootjQuery; //处理标签 div p li if (typeof selector === "string") { return ( context || root ).find(selector); } else if (selector.nodeType) { this.context = this[0] = selector; this.length = 1; return this; } }; init.prototype = myJQuery.fn; rootjQuery = myJQuery(document); if (!noGlobal) { window.myJQuery = window.F$ = myJQuery; } return myJQuery; });
JQuery源码解析--callbacks的更多相关文章
- jquery源码解析:代码结构分析
本系列是针对jquery2.0.3版本进行的讲解.此版本不支持IE8及以下版本. (function(){ (21, 94) 定义了一些变量和函数, jQuery = function() ...
- JQuery源码解析(一)
写在前面:本<JQuery源码解析>系列是基于一些前辈们的文章进行进一步的分析.细化.修改而写出来的,在这边感谢那些慷慨提供科普文档的技术大拿们. 要查阅JQ的源文件请下载开发版的JQ.j ...
- jQuery 源码解析二:jQuery.fn.extend=jQuery.extend 方法探究
终于动笔开始 jQuery 源码解析第二篇,写文章还真是有难度,要把自已懂的表述清楚,要让别人听懂真的不是一见易事. 在 jQuery 源码解析一:jQuery 类库整体架构设计解析 一文,大致描述了 ...
- jquery源码解析:jQuery工具方法Callbacks详解
我们首先来讲下Callbacks是如何使用的:第一个例子 function a(){} function b(){} var cb = $.Callbacks(); cb.add(a); cb.add ...
- jQuery源码解析资源便签
最近开始解读jQuery源码,下面的链接都是搜过来的,当然妙味课堂 有相关的一系列视频,长达100多期,就像一只蜗牛慢慢爬, 至少品读三个框架,以后可以打打怪,自己造造轮子. 完全理解jQuery源代 ...
- jquery 源码解析
静态与实力方法共享设计 遍历方法 $(".a").each() //作为实例方法存在 $.each() //作为静态方法存在 Jquery源码 jQuery.prototype = ...
- 三.jQuery源码解析之jQuery的框架图
这张图片是对jQuery源码截图,一点一点拼出来的. 现在根据这张图片来对jQuery框架做一些说明. 一.16~9404行可以发现,最外层是一个自调用函数.当jQuery初始化时,这个自调用函数包含 ...
- 一.jQuery源码解析之总体架构
(function (window, undefined) { //构建jQuery对象 var document = window.document, navigator = window.navi ...
- jquery源码解析:addClass,toggleClass,hasClass详解
这一课,我们将继续讲解jQuery对元素属性操作的方法. 首先,我们先看一下这几个方法是如何使用的: $("#div1").addClass("box1 box2&quo ...
随机推荐
- KindEditor 编辑器使用方法
http://kindeditor.net/docs/usage.html 编辑器使用方法 1. 下载编辑器 下载 KindEditor 最新版本,下载之后打开 examples/index.html ...
- ant批量执行Jmeter脚本
JDK,Jmeter默认已经装了 ANT下载:http://ant.apache.org/bindownload.cgi ant环境变量需要配置 ant_home,你解压之后的地址 然后PATH环境变 ...
- TableViewCell,TableView,UITableViewCell
这次的学习是在Navigation-based Application模板中,用RootViewController class设置操作方法,使用UITableView的属性值.在导航控制器控件为程序 ...
- 虚拟机下linux安装mysql,apache和php
由于腿伤了,卧床在家折腾下linux,尝试用虚拟机装mysql,apche和php.中间各种波折,装了好几天,觉得有些经验还是要记录下来,让自己别忘了:) 按照下面这篇文章的方法,基本可以顺利安装成功 ...
- 解决MD5问题
使用VS时报错此实现不是 Windows 平台 FIPS 验证的加密算法的一部分. 解决方案如下:在window中打开功能里输入regedit,回车打开注册器.然后进入如下路径中 HKEY_LOCAL ...
- phthon
没什么特别的,我们项目的跨平台代码都是在Windows环境下编码,然后跨平台编译调试,C++和Python代码都是如此.我们用C++实现底层和框架,用ctypes将纯C的API给Python化,然后用 ...
- 头像上传,拖拽,裁切(HTML5)版本
演示地址: http://codeman35.itongyin.com:19002/v1/web_demo.html 功能: 支持滚轴放大缩小,鼠标拖动,裁切可视区域
- 向IPython Notebook中导入.py文件
IPython Notebook使用起来简洁方便,但是有时候如果需要导入一个现有的.py文件,则需要注意选择导入的方法以达到不同的效果.目前遇到3种方法. (1) 将文件保存为.ipynb格式,直接拖 ...
- java封装学习
封装:将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问.把过程和数据包围起来,对数据的访问只能通过已定义的接口. 在java中通过关键字priva ...
- Druid监控Mybatis不显示SQL问题
一.Web.xml增加如下配置: 1.DruidWebStatFilter.如果没有配置filter信息.session监控,web监控等不可用.没有配置 <filter> <fil ...