jquery源码解析:jQuery原型方法init的详解
先来了解几个jQuery方法:
<li></li>
<li></li>
<li></li>
$("li") -> this -> jQuery对象 -> { 0 : "li", 1 : "li", 2 : "li", length : 3 }
$("<li>aaa") 的效果跟 $("<li>")的效果是一样的。
然后来看一下init方法,也就是新建jQuery对象调用的方法:
jQuery.fn = jQuery.prototype = {
jquery: core_version, //jQuery的版本
constructor:jQuery, //修正constructor的指向,不写这个的话,constructor会指向Object,因为你重写了JQuery的prototype。
//新建一个构造函数时,会自动在构造函数的prototype对象中新添constructor属性(指向构造函数)。但是为了防止原型对象的覆盖,比如:Person.prototype = {};这时里面的constructor指向会出问题,需要修正,Person.prototype = { constructor: Person}
init:function(selector,context,rootjQuery){
var match,elem;
if(!selector){ //处理这种情况:$(""), $(null), $(undefined), $(false)
return this;
}
if ( typeof selector === "string" ) {
if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
// $("<li>") -> match = [ null, "<li>", null ];
// $("<li>1</li><li>2</li>") -> match = [ null, "<li>1</li><li>2</li>", null ];
match = [ null, selector, null ];
} else {
// 此正则rquickExpr匹配后,会出现以下几种情况:
// 1. match = null; $(".box"), $("div"), $("#div1 div.box")
// 2. match = ["#div1",null,"div1"]; $("#div1")
// 3. match = ["<li>aaa","<li>",null]; $("<li>aaa")
match = rquickExpr.exec( selector );
}
// $("#div1")通过id匹配元素,是在document中执行,不会传入context,所以context为空,因此进入if语句
if ( match && (match[1] || !context) ) {
if ( match[1] ) { // $("<li>"), $("<li>aaa"),$("<li>1</li><li>2</li>")
//context就是document,因为创建元素只能在document中执行。但是页面里面有iframe时,iframe中的document与页面的document不同,所以$("<li>",document)有第二个参数。一般用不上。
context = context instanceof jQuery ? context[0] : context;
//$("<li>",$(document)),得到原生的document。
jQuery.merge( this, jQuery.parseHTML(match[1],context && context.nodeType ? context.ownerDocument || context : document,
true
) );
//parseHTML方法:第一个参数传入标签字符串"<li>",第二个参数传入执行上下文document,第三个参数true代表可以新建script标签"<script><\/script>"(script前面的反斜杠需要转义,其他标签不需要),false代表不能。返回值是一个数组:$("<li>") -> ["li"], $("<li>1</li><li>2</li>") ->["li","li"]
//merge方法是把数组转换成jQuery对象:["li"] -> {0:"li",length:1} ;["li","li"] -> {0:"li",1:"li",length:2}
rsingleTag匹配单标签的,$("<li>"),$("<li></li>")
if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {
//$("<li>",{title:"hi",html:"abcd"}) 针对这种情况的,context 为json对象。
for ( match in context ) {
//如果属性是jQuery方法,就执行方法
if ( jQuery.isFunction( this[ match ] ) ) {
this[ match ]( context[ match ] );
} else {
//如果不是方法,就设置属性。
this.attr( match, context[ match ] );
}
}
}
return this;
}
else {
elem = document.getElementById( match[2] );
// Blackberry 4.6:elem存在,但是页面上没有,所以添加了elem.parentNode,如果都满足,则elem一定存在页面上。
if ( elem && elem.parentNode ) {
this.length = 1;
this[0] = elem;
}
this.context = document;
this.selector = selector; //"#div"
return this;
}
}
else if ( !context || context.jquery ) {
return ( context || rootjQuery ).find( selector ); //rootjQuery = $(document)
// 处理这种$(expr, context),context是否是jQuery对象(context.jquery存在就是jQuery对象),会转换成$(context).find(expr)
//或者$(expr),会转换成$(document).find(expr)
}
else { //如果context存在,但是不是jQuery对象,就执行
return this.constructor( context ).find( selector ); //新建jQuery对象,并调用find方法
}
}
else if ( selector.nodeType ) { //如果是dom节点,比如:$(document)
this.context = this[0] = selector;
this.length = 1;
return this;
}
else if ( jQuery.isFunction( selector ) ) { //文档加载有两种方式:$(function(){});$(document).ready(function(){});
return rootjQuery.ready( selector );
}
if ( selector.selector !== undefined ) { //$($("#div1")),当传入jQuery对象时
this.selector = selector.selector;
this.context = selector.context;
}
return jQuery.makeArray( selector, this ); //传入数组和json对象时,比如:$([]),$({})
//makeArray把selector(类数组)转换成数组(外部使用),当传入第二个参数时(内部使用),就会转换成jQuery对象的形式。
},
length:0, //匹配到的元素的长度,默认为0.
......
};
加油!
jquery源码解析:jQuery原型方法init的详解的更多相关文章
- jQuery 源码解析(三十) 动画模块 $.animate()详解
jQuery的动画模块提供了包括隐藏显示动画.渐显渐隐动画.滑入划出动画,同时还支持构造复杂自定义动画,动画模块用到了之前讲解过的很多其它很多模块,例如队列.事件等等, $.animate()的用法如 ...
- jQuery 源码分析(十九) DOM遍历模块详解
jQuery的DOM遍历模块对DOM模型的原生属性parentNode.childNodes.firstChild.lastChild.previousSibling.nextSibling进行了封装 ...
- jQuery 源码解析(三) pushStack方法 详解
该函数用于创建一个新的jQuery对象,然后将一个DOM元素集合加入到jQuery栈中,最后返回该jQuery对象,有三个参数,如下: elems Array类型 将要压入 jQuery 栈的数组元素 ...
- jQuery 源码分析(十) 数据缓存模块 data详解
jQuery的数据缓存模块以一种安全的方式为DOM元素附加任意类型的数据,避免了在JavaScript对象和DOM元素之间出现循环引用,以及由此而导致的内存泄漏. 数据缓存模块为DOM元素和JavaS ...
- jQuery源码分析(九) 异步队列模块 Deferred 详解
deferred对象就是jQuery的回调函数解决方案,它解决了如何处理耗时操作的问题,比如一些Ajax操作,动画操作等.(P.s:紧跟上一节:https://www.cnblogs.com/grea ...
- 十七.jQuery源码解析之入口方法Sizzle(1)
函数Sizzle(selector,context,results,seed)用于查找与选择器表达式selector匹配的元素集合.该函数是选择器引擎的入口. 函数Sizzle执行的6个关键步骤如下: ...
- jQuery 源码解析二:jQuery.fn.extend=jQuery.extend 方法探究
终于动笔开始 jQuery 源码解析第二篇,写文章还真是有难度,要把自已懂的表述清楚,要让别人听懂真的不是一见易事. 在 jQuery 源码解析一:jQuery 类库整体架构设计解析 一文,大致描述了 ...
- jquery源码解析:代码结构分析
本系列是针对jquery2.0.3版本进行的讲解.此版本不支持IE8及以下版本. (function(){ (21, 94) 定义了一些变量和函数, jQuery = function() ...
- JQuery源码解析(一)
写在前面:本<JQuery源码解析>系列是基于一些前辈们的文章进行进一步的分析.细化.修改而写出来的,在这边感谢那些慷慨提供科普文档的技术大拿们. 要查阅JQ的源文件请下载开发版的JQ.j ...
随机推荐
- Gouraud Shading
[Gouraud Shading] Gouraud Shading (高洛德着色/高氏着色) 这种着色的效果要好得多,也是在游戏中使用最广泛的一种着色方式.它可对3D模型各顶点的颜色进行平滑.融合处理 ...
- Ztree右键事件,如何让指定的子节点不显示右键菜单。
这里我记录一下我自己的解决方案: 1.首先在Ztree的setting设置中加一个鼠标右键回调函数onRightClick,然后在加一个beforeRightClick(具体含义可以看官方API) v ...
- Python3 模块与包
一.模块介绍 什么是模块? 常见的场景:一个模块就是一个包含了一组功能的Python文件,比如spam.py,模块名为spam,可以通过import spam使用. 在Python中,模块的使用方式都 ...
- msyql中子查询IN,EXISTS,ANY,ALL,SOME,UNION介绍
1.ANY关键字 假设any内部的查询语句返回的结果个数是三个,如:result1,result2,result3,那么, select ...from ... where a > any(.. ...
- 读取位图(bitmap)实现及其要点
位图的格式如下: 1.文件头信息块 0000-0001 :文件标识,为字母ASCII码“BM”. 0002-0005 :文件大小. 0006-0009 :保留,每字节以“00”填写. 000A-000 ...
- It's not too late to start!
It's not too late to start! 以此鼓励,希望能坚持下去,一个半路自学PHP的准PHPer!
- Red Hat 6.5 Samba服务器的搭建(登录访问)
搭建Samba服务器是为了实现Linux共享目录之后,在Windows可以直接访问该共享目录. 现在介绍如何在红帽6.5系统中搭建Samba服务. 搭建Samba服务之前,yum源必须配置好,本地源和 ...
- JS中关于位置和尺寸的api
HTMLElement.offsetParent 由于offsetTop 和 offsetLeft 都是相对于 offsetParent 内边距边界的,故offsetParent的意义十分重大.off ...
- springboot+swagger集成
一.swagger介绍 Swagger 是一款RESTFUL接口的文档在线自动生成+功能测试功能软件.本文简单介绍了在项目中集成swagger的方法和一些常见问题.如果想深入分析项目源码,了解更多内容 ...
- win7设置开机启动virtualBOX虚拟机
如果常用VirtualBox虚拟机系统的话,设置随开机启动也是很方便的.不需要打开VirtualBox窗口,直接启动VirtualBox虚拟机系统就可以了. 设置开机自启动VirtualBox虚拟机系 ...