jQuery 源码分析2: jQuery.fn.init
//jQuery.fn.intit 中使用到的外部变量: // 判断是否为HTML标签或#id
rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/; // window.document的jQuery对象
rootjQuery = jQuery(window.document); // 判断是否为HTML标签
rsingleTag = (/^<(\w+)\s*\/?>(?:<\/\1>|)$/); init = jQuery.fn.init = function( selector, context ) {
var match, elem; // 处理空selector $(""), $(null), $(undefined), $(false)
if ( !selector ) {
return this; // 返回空jQuery对象
}
// 处理 HTML 字符串
if ( typeof selector === "string" ) {
if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
// 如果头尾含有 "<", ">"则跳过正则表达式检查
match = [ null, selector, null ];
} else {
match = rquickExpr.exec( selector ); // 使用正则表达式检查是否为#id或HTML标签
}
// 确定是一个html标签,或为#id时没有特定的上下文
if ( match && (match[1] || !context) ) {
// HANDLE: $(html) -> $(array)
if ( match[1] ) {
context = context instanceof jQuery ? context[0] : context;
// jQuery.merge把jQuery.parseHTML的返回值合并到this上
// jQuery.parseHTML将HTML字符串转换为一个DOM节点的集合
// 如果context不为空则以conext节点为上下文来创建HTML片段
// jQuery.parseHTML中的参数true表明保留HTML字符串中的脚本
// 如果parseHTML方法不存在则会抛出异常
jQuery.merge( this, jQuery.parseHTML(
match[1],
context && context.nodeType ? context.ownerDocument || context : document,
true
) );
// jQuery(html, attributes),example
// $( "<div></div>", {
// "class": "my-div",
// on: { touchstart: function( event ) {// Do something}
// }
// })
// rsingleTag检测字符串时候为一个HTML tag
// jQuery.isPlainObject 判断context是否为纯粹的对象字面量
// 纯粹对象字面量表明这个对象是有new或{}创建的,它有构造器,有原型链继承,但要排除window或DOM对象 // 如果context不是纯粹对象字面量,for in 语句操作可能会出错
if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {
for ( match in context ) {
// 调用自身的方法
if ( jQuery.isFunction( this[ match ] ) ) {
this[ match ]( context[ match ] );
// 设置属性
} else {
this.attr( match, context[ match ] );
}
}
}
return this;
// $('#id') 选择id
} else { // 直接利用document的方法来说实现
elem = document.getElementById( match[2] );
// Check parentNode to catch when Blackberry 4.6 returns
// nodes that are no longer in the document #6963
// Blackberry4.6 返回时有parentNode
if ( elem && elem.parentNode ) { // IE和Opera的返回对象是第一个name符合的对象
if ( elem.id !== match[2] ) { // 如果ID错误,在rootjQuery中用find查找
return rootjQuery.find( selector );
}
// 如果不存在这个节点,则插入一个
this.length = 1;
this[0] = elem;
}
this.context = document; // 添加上下文
this.selector = selector; // 更改选择器为id
return this;
}
// 选择器表达式: $(expr, $(...)) // 如果context为空或context是一个jQuery对象,jQuery.jquery存放version信息
} else if ( !context || context.jquery ) {
return ( context || rootjQuery ).find( selector );
// 选择器表达式: $(expr, context)
// 等同于: $(context).find(expr)
} else { // 利用jQuery构造器调用context
return this.constructor( context ).find( selector );
}
// $(a_node), 一个DOM节点元素
} else if ( selector.nodeType ) { // 直接把该节点添加到this上
this.context = this[0] = selector;
this.length = 1;
return this;
// selector 是一个function, 调用jQuery.ready(func) 的快捷方式
} else if ( jQuery.isFunction( selector ) ) {
return typeof rootjQuery.ready !== "undefined" ?
rootjQuery.ready( selector ) :
// 如果ready方法不存在,则立即执行
selector( jQuery );
}
if ( selector.selector !== undefined ) { // 如果选择器包含其他属性,赋值给this的同名属性
this.selector = selector.selector;
this.context = selector.context;
} // 将selector合并到this上
return jQuery.makeArray( selector, this );
};
- 处理空selector,相当于返回jQuery方法接口
- 判断HTML字符串
- HTML字符或#id
- 单独HTML标签,创建DOM对象并插入
- #id,使用document.getElementById获取DOM对象
- 选择器表达式,使用$.find
- 函数,注册到ready或立即执行
- DOM对象,直接返回
jQuery 源码分析2: jQuery.fn.init的更多相关文章
- jQuery源码分析之=>jQuery的定义
最近写前段的代码比较多,jQuery是用的最多的一个对象,但是之前几次看了源码,都没搞清楚jQuery是怎么定义的,今天终于看明白怎么回事了.记录下来,算是一个新的开始吧. (文中源码都是jQuery ...
- jQuery 源码分析3: jQuery.fn/ jQuery.prototype
// 建立方法实例,提高方法访问的速度(避免在原型链上搜索) var deletedIds = []; var slice = deletedIds.slice; var concat = delet ...
- jQuery 源码分析4: jQuery.extend
jQuery.extend是jQuery最重要的方法之一,下面看看jQuery是怎样实现扩展操作的 // 如果传入一个对象,这个对象的属性会被添加到jQuery对象中 // 如果传入两个或多个对象,所 ...
- 六.jQuery源码分析之jQuery原型属性和方法
97 jQuery.fn = jQuery.prototype = { 98 constructor: jQuery, 99 init: function( selector, context, ro ...
- jQuery 源码分析6: jQuery 基本静态方法(二)
jQuery.extend({ // 遍历obj的所有值 // args 这参数只能内部调用的会用到 // 注意到,如果回调函数调用失败会直接跳出并中止遍历 // 当有args数组时,使用apply调 ...
- jQuery 源码分析5: jQuery 基本静态方法(一)
jQuery在初始化过程中会为自己扩展一些基本的静态方法和属性,以下是jQuery 1.11.3版本 239 ~ 564行间所扩展的静态属性和方法 jQuery.extend({ // 为每个jQ ...
- jQuery 源码分析 8: 回头看jQuery的构造器(jQuery.fn,jQury.prototype,jQuery.fn.init.prototype的分析)
在第一篇jQuery源码分析中,简单分析了jQuery对象的构造过程,里面提到了jQuery.fn.jQuery.prototype.jQuery.fn.init.prototype的关系. 从代码中 ...
- Jquery源码分析-整体结构
最近在学习Jquery的最新的源码,Jquery-3.3.1版本.网上有很多对jquery解析的文章.但是我还是要自己去尝试着看一篇jquery的源码.本系列博客用来记录其中的过程,并同大家分享.本次 ...
- jQuery源码分析系列
声明:本文为原创文章,如需转载,请注明来源并保留原文链接Aaron,谢谢! 版本截止到2013.8.24 jQuery官方发布最新的的2.0.3为准 附上每一章的源码注释分析 :https://git ...
随机推荐
- HW机试字符串压缩java(1)
package huawei; public class StringZip { public static String stringZip(String a) { String ans =&quo ...
- input子系统分析
------------------------------------------ 本文系本站原创,欢迎转载! 转载请注明出处:http://ericxiao.cublog.cn/ -------- ...
- Storm系列(六)架构分析之Scheduler-调度器[EventScheduler]
任务调度接口定义: 1 IScheduler{ 2 // conf为当前nimbus的stormp配置 3 void prepare(Map conf); // 初始化 4 // to ...
- POJ1502: MPI Maelstrom
红果果的dijstra算法应用,这里采用邻接表存储图 小插曲:while(scanf("%d",&n))提交时内存超限,改成while(scanf("%d&quo ...
- 最常用的Java库一览
本文由 ImportNew - 邢 敏 翻译自 programcreek.欢迎加入翻译小组.转载请见文末要求. 写在前面: 1) 本文列出的名单是根据我自己的调查,并结合个人的经验.有可能是它们不恰恰 ...
- 高效Linux用户需要了解的命令行技能
最近在Quora上看到一个问答题目,关于在高效率Linux用户节省时间Tips. 将该题目的回答进行学习总结,加上自己的一些经验,记录如下,方便自己和大家参考. 下面介绍的都是一些命令行工具,这些工具 ...
- JavaScript----this陷阱的最全收集
原文翻译: JavaScript来自一门健全的语言,所以你可能觉得JavaScript中的this和其他面向对象的语言如java的this一样,是指存储在实例属性中的值.事实并非如此,在JavaScr ...
- Android5.0常用颜色属性说明
在使用Eclipse的时代,我们很少去在style文件给整个应用或者Activity去设定颜色,那是因为即使设置也不会提升用户的视觉效果.但是材料设计号称让没有设计功底的人也能做出漂亮的App,那我们 ...
- zepto的scrollTo,实现锚点跳转
实现功能:点击右侧字母A,实现锚点跳转功能: 有同学可能说可以直接用锚点跳转实现,是的,锚点跳转可以实现这个功能,但是有一个问题,点击跳转后,再点击返回,返回的是上次跳转的结果,具体的原理就不用多说了 ...
- c++匿名类—指针
1 摘自网上 2代码实例 #include <iostream> #include <list> #include <iterator> #include < ...