jQuery 源码分析(二) 入口模块
jquery返回的对象本质上是一个javascript对象,而入口模块则可以保存对应的节点的引用,然后供其它模块操作
我们创建jquery对象时可以给jquery传递各种不同的选择器,如下:
false ;返回一个空jquery对象
dom节点 ;返回包含该dom元素引用的jquery对象。
body ;字符串'body',返回包含body元素引用的jquery对象
单独标签 ;调用document.createelement创建标签对应的dom元素
较复杂的html代码 ;调用jquery.buildfragment创建元素
函数 ;是$(document).ready(function)的简写,等到dom加载完毕后再执行,后面有几篇专门介绍
例如:
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>document</title> <script src="http://libs.baidu.com/jquery/1.7.1/jquery.min.js"></script> </head> <body> <p id="p">123</p> <script> console.log( $(false) ) console.log( $(p) ) console.log( $('body') ) console.log( $('<p>123</p>') ) $(function(){console.log('dom loaded')}) </script> </body> </html>
输出如下:
输出的五条信息分别对应上面的五个输出,第一条为空jquery对象,第二条为包含p元素的jquery对象,第三条为包含body节点引用的jquery对象,第四条为jquery创建的未挂载到dom的jquery对象,第五条就直接输出信息的,对应着例子的$(function(){})对象
源码分析
writer by:大沙漠 qq:22969969
入口模块就是上一篇文章分析的jquery内部的jquery.fn.init函数,该函数会通过参数的不同来做不同的实现,如下:
init: function( selector, context, rootjquery ) { //负责解析参数selector和context的类型,并执行相应的逻辑 var match, elem, ret, doc; // handle $(""), $(null), or $(undefined) if ( !selector ) { //selector是"",null,undefined和false的等可以转换为false的情况下,对应上面的第一个jquery实例 return this; } // handle $(domelement) if ( selector.nodetype ) { //selector有属性nodetype,则认为selector是dom元素,例如:$(document.getelementbyid('d')),对应上面的第二个jquery实例 this.context = this[0] = selector; this.length = 1; return this; } // the body element only exists once, optimize finding it if ( selector === "body" && !context && document.body ) { //如果参数selector是字符串'body',且context为空,如:$('body'),对应上面的第三个jquery实例 this.context = document; this[0] = document.body; this.selector = selector; this.length = 1; return this; } // handle html strings if ( typeof selector === "string" ) { //参数selector是字符串形式 // are we dealing with html string or an id? if ( selector.charat(0) === "<" && selector.charat( selector.length - 1 ) === ">" && selector.length >= 3 ) { //如果参数selector以"<"开头、以">"结尾,且长度大于等于3 // assume that strings that start and end with <> are html and skip the regex check match = [ null, selector, null ]; //则假设这个字符串是html片段,跳过正则quickexpr的检查。注意这里仅仅是假设,并不一定表示它是真正合法的html代码 } else { match = quickexpr.exec( selector ); //否则用quickexpr来检测参数selector是否为稍微复杂一点的代码, } // verify a match, and that no context was specified for #id if ( match && (match[1] || !context) ) { // handle: $(html) -> $(array) if ( match[1] ) { context = context instanceof jquery ? context[0] : context; doc = ( context ? context.ownerdocument || context : document ); // if a single string is passed in and it's a single tag // just do a createelement and skip the rest ret = rsingletag.exec( selector ); if ( ret ) { //如果参数selector是单独标签比如$('<p></p>'); if ( jquery.isplainobject( context ) ) { selector = [ document.createelement( ret[1] ) ]; jquery.fn.attr.call( selector, context, true ); } else { selector = [ doc.createelement( ret[1] ) ]; } } else { ret = jquery.buildfragment( [ match[1] ], [ doc ] ); selector = ( ret.cacheable ? jquery.clone(ret.fragment) : ret.fragment ).childnodes; } return jquery.merge( this, selector ); // handle: $("#id") } else { //参数selector是"#id"格式,如:$('#p1') elem = document.getelementbyid( match[2] ); // check parentnode to catch when blackberry 4.6 returns // nodes that are no longer in the document #6963 if ( elem && elem.parentnode ) { // handle the case where ie and opera return items // by name instead of id if ( elem.id !== match[2] ) { return rootjquery.find( selector ); } // otherwise, we inject the element directly into the jquery object this.length = 1; this[0] = elem; } this.context = document; this.selector = selector; return this; } // handle: $(expr, $(...)) } else if ( !context || context.jquery ) { return ( context || rootjquery ).find( selector ); // handle: $(expr, context) // (which is just equivalent to: $(context).find(expr) } else { return this.constructor( context ).find( selector ); } // handle: $(function) // shortcut for document ready } else if ( jquery.isfunction( selector ) ) { //如果参数selector是函数,则认为是绑定ready事件,从这里可以看出$(function) 是$(document).ready(function)的简写,这里对应上面的第五个jquery实例 return rootjquery.ready( selector ); } if ( selector.selector !== undefined ) { this.selector = selector.selector; this.context = selector.context; } return jquery.makearray( selector, this ); },
这样jquery实例就获取到了对应的dom节点的引用,之后就可以用底层模块或功能模块进行操作了。
上一篇: 传台积电为华为腾挪部分订单
下一篇: oracle控制文件相关命令
推荐阅读
-
Mybaits 源码解析 (九)----- 全网最详细,没有之一:一级缓存和二级缓存源码分析
-
jQuery选择器源码解读(二):select方法
-
Tomcat源码分析 (二)----- Tomcat整体架构及组件
-
jQuery 源码解析(二十九) 样式操作模块 尺寸详解
-
jQuery 源码分析(十八) ready事件详解
-
jQuery 源码分析(十八) ready事件详解
-
jQuery 源码分析(四) each函数 $.each和$.fn.each方法 详解
-
jQuery 源码分析笔记
-
jQuery源码分析之jQuery.fn.each与jQuery.each用法
-
netty之NioEventLoopGroup源码分析二