首先我们给出下面的HTML代码:
<div id="parent" class="parent">
<div class="child">
child1
</div>
<div class="child">
child2
</div>
</div>
<div id="parent1" class="parent">
<div class="child">
child1
</div>
<div class="child">
child2
</div>
</div>
调用方式1:第二个参数context是DOM元素
var doms=$(".child",$("#parent")[0]);
console.log(doms);
这时候第二个参数是DOM对象,打印[div.child, div.child, prevObject: jQuery.fn.init[1], context: div#parent, selector: ".child"]
调用方式2:第二个参数context是jQuery对象
var doms=$(".child",$($("#parent")[0]));
console.log(doms);
这时候打印结果和上面第一种情况一样,[div.child, div.child, prevObject: jQuery.fn.init[1], context: div#parent, selector: ".child"]
调用方式3:第二个参数是一个DOM数组
var doms=$(".child",[document.getElementById("#parent"),document.getElementById("#parent1")])
console.log(doms);
调用方式4:第二个参数是一个jQuery对象数组
var doms=$(".child",$(".parent"))
console.log(doms);
这种方式的结果和第三种方式是完全一样的!
调用方式5:传入的参数是一个函数,该函数会在ready函数调用的时候调用
$(function()
{
console.log("dom ready");
})
我们现在从
源码中分析这几种情况:
如果传入DOM的情况
else if ( selector.nodeType ) {
this.context = this[0] = selector;
this.length = 1;
return this;
// HANDLE: $(function)
// Shortcut for document ready
}
如果传入DOM元素,那么直接把元素放在jQuery对象上面,同时把length自增!
如果传入了jQuery对象
if ( selector.selector !== undefined ) {
this.selector = selector.selector;
this.context = selector.context;
}
如果传入了jQuery对象,那么也是把参数jQuery的selector和context直接封装到新创建的jQuery对象上面!调用方式如$($(''))这种方式!
如果传入的是一个函数
else if ( jQuery.isFunction( selector ) ) {
return typeof rootjQuery.ready !== "undefined" ?
rootjQuery.ready( selector ) :
// Execute immediately if ready is not present
selector( jQuery );
}
如果传入了一个函数,那么直接放在$(document).ready()中等待执行,如果没有ready函数那么直接执行(使用了jQuery框架那么ready是存在的!)
如果是传入了一个DOM数组或者jQuery的对象
return jQuery.makeArray( selector, this );
通过jQuery.makeArray我们可以把所有的参数封装到一个对象上面,但是这个函数第二个参数默认是数组对象,但是这里传入了jQuery对象,那么最后返回的结果就是jQuery对象。因此,我们通过这种方式把我们传入的DOM数组或者jQuery对象全部封装到一个新的jQuery对象上面返回!这种方式的调用如下:
var $doms=$([document.getElementById('ql'),document.getElementById('fkl')]);
//把上面的DOM数组封装到新创建的jQuery对象上
console.log($doms);
下面这种调用方式是我们最常用的方式,该方式包含选择对象的上下文:
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 );
}
这种方式就是如$('li',$('ul'))第二个参数如果是jQuery对象,那么直接调用find方法,否则先把第二个参数的DOM对象封装为jQuery对象然后调用find方法进行查找!这种调用方式如下:
var doms=$(".child",$(".parent")) ;
//这时候我们会选择class为parent元素下的所有的class为child的元素集合
//作为jQuery对象返回
console.log(doms);
很显然,我们传入的第二个参数是jQuery对象,那么我们调用了Sizzle的find方法来进行查询,如果第二个参数是一个DOM数组,也会该DOM数组封装成为jQuery对象然后以此为上下文进行查询!
这时候我又要提一下这种调用方式(第二个参数可以是DOM数组)
var doms=$(".child",$(".parent"))
console.log(doms);
这时候通过的就是jQuery对象具有的find实例方法来完成的(调用Sizzle来完成),所以返回的就是DOM数组中每一个DOM对象的所有的满足selector的子元素组成的集合,但是这是去重的!
总之:jQuery允许我们为context传入一个jQuery对象或者DOM数组,表示以该DOM数组或者jQuery对象为上下文的满足selector的所有的元素集合,很酷的一个方法!
// HANDLE: $(html, props)
if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {//<div/>或者<div></div>或<div>形式处理
for ( match in context ) {
// Properties of context are called as methods if possible
if ( jQuery.isFunction( this[ match ] ) ) {//如果是内置函数
this[ match ]( context[ match ] );//调用html('')
// ...and otherwise set as attributes
} else {
this.attr( match, context[ match ] );//不是函数直接设置属性!
}
}
}
这种方式允许我们按照下面这种方式来创建元素的同时指定元素应该具有的属性
$("<li>",{tile:"abcd",html:'abcn'})
如果是jQuery对象具有的函数,那么我们执行,如这里的html方法就是jQuery对象具有的内置的函数,所以我们执行他html('abcn'),传入参数是'abcn'。而title不是内置方法,所以直接通过调用attr方法来为我们创建的元素指定属性!
下面这种方式允许我们创建一个复杂的DOM元素:
jQuery.merge( this, jQuery.parseHTML(match[1],context && context.nodeType ? context.ownerDocument || context : document,true) );
而且第三个参数是true,表示我们可以创建script元素!该用法
参见jQuery.parseHTML用法。
总结:
这里只是给出了几种我觉得应该掌握的情况,如果需要详细了解,请参见init方法!