jQuery技术内幕:深入解析jQuery架构设计与实现原理.pdf
总体架构
入口模块
构造 jQuery 对象,jQuery()
底层支持模块
- 工具方法 Utilities
- 回调函数列表 Callbacks Object
- 异步队列 Deferred Object
- 浏览器功能测试 Support
- 数据缓存 Data
- 队列 Queue
- 选择器 Sizzle
功能模块
- 属性操作 Attributes
- 事件系统 Events
- DOM 遍历 Traversing
- DOM 操作 Manipulation
- 样式操作 CSS
- 计算样式 & 内联样式
- 坐标 Offset
- 尺寸 Dimensions
- 异步请求 Ajax
- 动画 Effects
自调用匿名函数
创建了一个特殊的函数作用域,该作用域中的代码不会和已有的同名函数、方法和变量以及第三方库冲突
// 写法 1
(function(){})();
// 写法 2
(function(){}());
// 写法 3
!function(){}();
将 window 传入到自调用匿名函数中:
- 使 window 变为局部变量,当在 jQuery 中访问 window 对象时,不需要将作用域链回退到顶层作用域,从而更快地访问 window 对象
- 将 window 作为参数传入,可以在压缩代码时进行优化,参数 window 会被压缩为 a
// 写法 1
(function(){})(window);
将 undefined 传入到自调用匿名函数中:
(function(window, undefined){})(window);
- 变为局部变量,更快
- 压缩代码优化
- 确保参数 undefined 的值是 undefined,防止 undefined 被重写为新的值
构造 jQuery 对象
7种用法
jQuery(selector[,context])
:接收一个CSS选择器表达式和可选的选择器上下文,返回一个包含了匹配的DOM元素的 jQuery 对象jQuery(html[,ownerDocument]) | jQuery(html[,props])
:用提供的 HTML 代码创建 DOM 元素jQuery(element) | jQuery(elementArray)
:封装 DOM 元素为 jQuery 对象jQuery(object)
:封装普通对象为 jQuery 对象jQuery(callback)
:绑定 ready 事件监听函数,当 DOM 结构加载完成时执行jQuery(jQuery object)
:接受一个 jQuery 对象,返回该 jQuery 对象的拷贝副本jQuery()
:创建一个空 jQuery 对象
jQuery.fn.init(selector,context,rootjQuery) 的12分支
处理方式 | |
---|---|
!selector | return this |
selector.nodeType | this.context = this[0] = selector; this.length = 1; return this; |
“body” | this.context = document; this[0] = document.body; this.selector = selector; this.length = 1; return this; |
“string” 6个分支 | 单独标签: 复杂 HTML:jQuery.buildFragment #id: document.getElementById $(selector): return rootjQuery.find(selector); $(selector, $(…)): return context.find(selector); $(selector, context): return this.constructor(context).find(selector) |
function | return rootjQuery.ready(selector); |
$($(…)) | this.selector = selector.selector; this.context = selector.context; |
任意其他值 | return jQuery.makeArray(selector, this) |
选择器 Sizzle
http://api.jquery.com/category/selectors/
http://sizzlejs.com
sizzle 是一款纯 JS 实现的 CSS 选择器引擎:
- 完全独立,无库依赖
- 相较于大多数常用选择器其性能非常有竞争力
- 压缩和开启 gzip 后只有 4KB
- 具有高扩展性和易于使用的 API
- 支持多种浏览器:IE6+
如果浏览器支持 querySelectorAll()
则调用该方法查找元素,如果不支持,则模拟该方法的行为。
选择器表达式
- 块表达式
- 简单表达式:ID、CLASS、TAG
- 属性表达式:ATTR
- 伪类表达式:PSEUDO
- 位置伪类 POS
- 子元素伪类 CHILD
- 内容伪类
- 可见伪类
- 表单伪类
块间关系符:
从左向右:先查找 “div.red” 匹配的元素集合,然后查找匹配 “p” 的子元素集合
从右往左:先查找 “p” 匹配的元素集合,然后检查其中每个元素的父元素是否匹配 “div.red“
处理选择器表达式:解析选择器表达式中的块表达式和块间关系符
- 处理块表达式:用块表达式的一部分查找,用剩余部分对查找结果进行过滤
处理块间关系符:按照块间关系符查找,用块表达式对查找结果进行过滤
从左往右:不断缩小上下文,即不断缩小查找范围
从右往左:先查找后过滤
从左往右:每次处理块间关系符时都需要处理未知数量的子元素或后代元素
- 从右往左:处理块间关系符时只需要处理单个父元素或有限数量的祖先元素
- 因此,多数情况,从右往左的查找方式其效果要高于从左往右
Sizzle 从右往左
- 正则 chunker 负责从选择器表达式中提取块表达式和块间关系符
Sizzle.find(expr, context, isXML)
负责查找块表达式匹配的元素集合Sizzle.filter(expr, set, inplace, not)
负责用块表达式过滤元素集合Sizzle.selector.relative
中的块间关系过滤函数根据块间关系符过滤元素集合
样式操作 CSS
分类 | 方法 | 说明 |
---|---|---|
内联样式 计算样式 |
.css(name, value) | 获取第一个匹配元素的计算样式,或者在每个匹配元素上设置一个或多个内联样式 |
类样式 | .addClass(value) | 为每个匹配元素添加一个或多个类样式 |
.removeClass(value) | 从每个匹配元素上移除一个或多个或全部类样式 | |
.toggleClass(value, stateVal) | 为每个匹配元素切换一个或多个或全部类样式 | |
.hasClass(selector) | 检测匹配元素是否含有指定的类样式,只要其中任意一个元素含有就返回true | |
坐标 | .offset(options) | 返回第一个匹配元素的文档坐标,或设置每个匹配元素的文档坐标 |
.position() | 返回第一个匹配元素相对于其最近定位祖先元素的坐标 | |
.scrollLeft() | 读取第一个匹配元素的滚动条的水平偏移,或设置每个匹配元素的滚动条的水平偏移 | |
.scrollTop() | 读取第一个匹配元素的滚动条的垂直偏移,或设置每个匹配元素的滚动条的垂直偏移 | |
尺寸 | .width(size) .height(size) |
返回第一个匹配元素计算后的高度、宽度,或设置每个匹配元素的高度、宽度,包括内容 content |
.innerWidth() .innerHeight() |
返回第一个匹配元素的高度、宽度,包括内容 content、内边距padding | |
.outerWidth(margin) .outerHeight(margin) |
返回第一个匹配元素的高度、宽度,包括内容content、内边距padding、边框border 和可选的外边框 margin |