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 ] );

//如果不是方法,就设置属性。

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.

......

};

加油!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值