这是我参与11月更文挑战的第12天,活动详情查看:2021最后一次更文挑战
1, 前言
上一章对jQuery的有一个全局的概念和了解,并简单的介绍了一下jQuery构造函数的7中用法,整体上总结了一下jQuery的总体结构,接下来针对jQuery的原型属性和方法,静态属性和方法以及一些核心的工具方法进行分析学习。
2, 回顾
针对上一章的代码,我们继续深入分析
(function(window, undefined) {
// 构造jQury对象
var jQuery = (function() {
var jQuery = function(selector, context) {
return new jQuery.fn.init(selector, context, rootjQuery)
}
jQuery.fn = jQuery.prototype = {
constructor: jQuery,
init: function(selector, context, rootjQuery){
// 原型方法和属性
}
};
jQuery.fn.init.prototype = jQuery.fn;
jQuery.extend = jQuery.fn.extend = function() {};
jQuery.extend({
// 静态方法和属性
})
return jQuery;
})();
window.jQuery = window.$ = jQuery
})(window)
3, jQuery.fn.init
通过上面的代码可以看出:jQuery.fn.init(selector, context, rootjQuery) 有三个参数,这个方法的作用主要是针对参数进行解析,并执行相应的逻辑,返回一个实例。
源码分析
init: function( selector, context, rootjQuery) {
var match, elem, ret, dec
}
-
selector参数:可以是任意类型的值,但只有undefined, DOM元素, 字符串,函数, jQuery对象, 普通js对象这几种类型是有效的。
-
context参数:可以不传入,或者传入DOM元素,jQuery对象,普通的JS对象
-
rootjQuery参数:包含了document对象的jQury对象
主要:selector不同的参数类型,函数的处理方式是不同的,可参考下面的截图:
4, jQuery.buildFragment
方法jQuery.buildFragment(args, nodes, scripts) 有三个参数,其原理是先创建一个文档片段DocumentFragment, 然后调用方法jQuery.clean(elems,context, fragment, scripts)将HMTL代码转换为DOM元素,并存储在创建的文档片段中。
注意: 此方法支持大量节点插入,相比于单个个的插入节点,使用DocumentFragment一次性插入多个节点,性能提升非常明显。
jQuery.buildFragment = function( arges, nodes, scripts) {
}
源码分析:次方法执行的顺序
1, 如果HTML代码符合缓存条件,则尝试从缓存对象jQuery.fragments中读取缓存的DOM元素
2,创建文档片段DocumentFragment
3, 调用jQuery.clean(elems, context, fragment,scripts)将HTML代码转换为DOM元素,
并存储在创建的文档片段中
4,如果HMTM代码符合缓存条件,则把转换后的DOM元素放入缓存对象jQuery.fragments
5,最好返回文档片段和缓存状态
{ fragement: fragment, cacheable: cacheable }
- args 参数:数组,待转换为DOM元素的HTML代码
- nodes 参数: 数组, 文档对象,jQuery对象或者DOM元素,
- scripts 参数:数组,用于存放HTML代码中的scritp元素,这个参数会被传递到jQuery.clean()中
截图是此方法的执行总结:
5, jQuery.clean
方法jQuery.clean(elems, context, fragment, scripts) 负责把HTML代码转换成DOM元素,并提取其中的script元素。该方法先创建一个临时的Div元素,并将其插入一个安全文档片段中,然后把HTML代码赋值给DIV元素的innerHTML属性,浏览器回自动生成DOM元素,最后解析DIV元素的子元素得到转换后的DOM元素。
jQuery.clean(elems, context, fragment, scripts)执行的8个步骤:
1,创建一个临时DIV元素,并插入一个安全文档片段中
2,为HTML代码包裹必要的父标签,然后赋值给临时DIV元素的innerHTML属性,从而将HTML代码转换为DOM元素,之后在层层剥去包裹的父元素,得到转换后的DOM元素
3,移除IE自动插入的空tbody元素,插入IE自动剔除的前导空白符
4,取到转换后的DOM元素集合
5,在IE中修复正复选框和单选框的选中状态
6,合并转换后的DOM元素
7,如果传入了文档片段,则提取所有合法的script元素存入数组,并把其他元素插入文档片段
8,最后返回转换后的DOM元素数组
- elemes 参数: 数组,包含了转换的HTML代码
- context 参数: 文档对象
- fragment 参数: 文档片段,作为存放转换后的DOM元素的占位符
- scripts 参数: 数组,用于存放转换后的DOM元素中的script元素
下面是该方法的执行总结
6, jQuery.extend()
方法jQuery.extend()和 jQuery.fn.enxtend() 用于合并两个或多个对象的属性到第一个对象,他们的语法:
jQuery.extend([deep], target, object1 [, objectN])
jQuery.fn.extend([deep], target, object1 [, objectN])
- deep 参数:是可选的布尔值,表示是否进行深度合并.
- target参数:是目标对象
- object1参数: 是源对象
如果提供了两个或者更多的对象,所有源对象的属性将会合并到目标对象,如果仅提供了一个对象,意味着参数target被忽略,jQuery被当作目标对象。
1, jQuery.extend()和 jQuery.fn.enxtend() 的执行步骤
(1) 修正参数deep, target,源对象的起始下标
(2) 遍历源对象, 遍历源对象的属性,覆盖目标对象的同名属性
7, 原型属性和方法
jQuery.fn = jQuery.prototype = {
constructor: jQuery,
init: function(selector, context, rootjQuery) {
}
selector: '',
jquery: '',
length: 0,
size: function() {},
toArray: function() {},
get: function(num) {},
pushStack: function(elems,name, selector) {},
each: function(callback, args) {},
ready: function(fn) {},
eq: function(i) {},
first: function() {},
last: function() {},
slice: function() {},
map: function(callback) {},
end: function() {},
push: push,
sort: [].sort,
splice: [].splice
}
原型属性和方法可总结为:jQuery.fn=jQuery.prototype
| .constructor | 指向构造函数 |
|---|---|
| .init(selector, context, rootjQuery) | 构造函数,解析参数,返回实例 |
| .selector | 记录jQuery查找和过滤DOM元素的选择器表达式 |
| .jquery | 正在使用的jQuery版本 |
| .length | jQuery对象中元素的个数 |
| .size() | 返回当前jQuery对象中元素的个数 |
| .toArray() | 将当前jQuery对象转换为真正的数组 |
| .get([index]) | 返回当前对象中指定位置的元素或包含了全部元素的数组 |
| .pushStack(element, name, args) | 创建一个新的空jQuery对象,然后把DOM元素集合放入这个jQuery对象中,并保留引用 |
| .each(function(index, element)) | 遍历当前jQury对象中的元素,并在每一个元素上执行的数组 |
| .ready(handle) | 绑定ready事件 |
| .eq(index) | 将匹配元素集合缩减为位于指定元素的新位置 |
| .first() | 将匹配元素集合缩减为集合中的第一个元素 |
| .last() | 将匹配元素集合缩减为集合中的最后一个元素 |
| .map(callback(index, ele)) | 遍历当前jQuery对象中的元素,并在每个元素上执行回调函数,返回一个新的对象 |
| .end() | 结束当前链条中最近的操作,并将匹配元素集合还原为之前的状态 |
| .push() | Array.prototype.push() |
| .sort() | [].sort |
| .splice() | [].plice |
| .slice() | 将匹配元素集合缩减为指定范围的子集 |