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 ...
随机推荐
- nand flash 和nor flash 区别
NOR和NAND是现在市场上两种主要的非易失闪存技术.Intel于1988年首先开发出NOR flash技术,彻底改变了原先由EPROM和EEPROM一统天下的局面.紧接着,1989年,东芝公司发表了 ...
- tmux快捷键`
Ctrl+b 激活控制台:此时以下按键生效 系统操作 ? 列出所有快捷键:按q返回 d 脱离当前会话:这样可以暂时返回Shell界面,输入tmux attach能够重新进入之前的会话 D 选择要脱离的 ...
- EGOImageView的使用方法及注意事项
1.下载EGOImageView及其相关的类库 EGOImageLoading 将EGOCache.EGOImageButton.EGOImageView.EGOImageLoader全部添加到工程下 ...
- http://www.cnblogs.com/xdp-gacl/p/3622275.html
http://www.cnblogs.com/xdp-gacl/p/3622275.html
- 多点触控之MotionEvent.ACTION_MASK作用
ACTION_MASK在Android中是应用于多点触摸操作,字面上的意思大概是动作掩码的意思吧. 在onTouchEvent(MotionEvent event)中,使用switch (event. ...
- JSON与JAVA数据的相互转换
http://www.cnblogs.com/linjiqin/archive/2011/09/19/2181408.html import net.sf.json.JSONArray; import ...
- PetShop 4.0学习笔记:消息队列MSMQ
直到今天才知道,在我们每天都在用的Window系统里还有这么好用的一个编程组件:消息队列.它能够解决在大数据量交换的情况下的性能问题,特别是BS系统的数据库性能.而且它的异步处理方式能给程序员最大的便 ...
- java实现window phone推送通知
package com.windowphone.text; import java.io.IOException;import java.io.OutputStream;import java.net ...
- Nginx/LVS/HAProxy负载均衡软件的优缺点详解(转)
PS:Nginx/LVS/HAProxy是目前使用最广泛的三种负载均衡软件,本人都在多个项目中实施过,参考了一些资料,结合自己的一些使用经验,总结一下. 一般对负载均衡的使用是随着网站规模的提升根据不 ...
- Android中的普通对话框、单选对话框、多选对话框、带Icon的对话框、以及自定义Adapter和自定义View对话框详解
对话框就是一个AlertDialog,但是一个简单的AlertDialog,我们却可以将它玩出许多花样来,下面我们就来一起总结一下AlertDialog的用法.看看各位童鞋在平时的工作中否都用到了Al ...