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 ...
随机推荐
- Webpack 入门指南 - 1.安装
Webpack 是目前流行的打包工具,如何安装它呢? 1. 安装 Node Js 首先,Webpack 是基于 NodeJs 的工具,你必须首先安装 NodeJs. NodeJs 仅仅只需要在你的系统 ...
- dubbo+zookeeper集群配置
集群服务注册到多台zookeeper配置: <dubbo:registry protocol="zookeeper" address="10.20.153.10:2 ...
- (windows)mongoDB3X+Robomongo的安装与基础配置
一开始安装的时候还觉得很简单真正装了时候发现网上的资料参差不齐再次整理一份安装方法 ---------------------------------------------------------- ...
- STL之序列式容器list与forward_list
List (双向链表) 与 forwardlist (单向链表) 算是非常基础的数据结构了,这里只是简单介绍下其结构及应用. 以list为例: 其节点模板: template <class T& ...
- 分拆素数和 HDU - 2098
把一个偶数拆成两个不同素数的和,有几种拆法呢? Input输入包含一些正的偶数,其值不会超过10000,个数不会超过500,若遇0,则结束.Output对应每个偶数,输出其拆成不同素数的个数,每个结果 ...
- 入门React和Webpack
最近在学习React.js,之前都是直接用最原生的方式去写React代码,发现组织起来特别麻烦,之前听人说用Webpack组织React组件得心应手,就花了点时间学习了一下,收获颇丰 说说React ...
- python 数据处理中各种存储方式里数据类型的转换
自己记录,仅供参考 在数据处理时经常会遇到数据类型不匹配的事情,为了方便查看各种存储方式中数据类型的改变.我把一些自己常用的整理方式记录下来,希望可以为以后数据类型的处理工作提供便利. 数据常用的基本 ...
- CSV表格读取
读取CSV表格需要CSV表格的编码格式为UTF-8 ,这个脚本中有些是为了方便使用封装的dll 不过都是一些简单的实现,自己实现也很容易,可做参考. /// <summary> /// 构 ...
- 使用HttpURLConnection下载图片
import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.net.Ht ...
- 【转】ELK(ElasticSearch, Logstash, Kibana)搭建实时日志分析平台
[转自]https://my.oschina.net/itblog/blog/547250 摘要: 前段时间研究的Log4j+Kafka中,有人建议把Kafka收集到的日志存放于ES(ElasticS ...