jQuery对象的入栈:实质就是返回一个新的jQuery对象,新的jQuery对象是由空jQuery对象合并参数元素后的结果,并在新的jQuery对象的prevObject属性保存着前一个(当前)jQuery对象
var div = $('div');//选中三个空的div
var div1 = $();
console.log(div);
console.log(div1);
<script>
window.onload = function(){
$('div').pushStack($('span')).css('background-color','red').prevObject.css('background-color','yellow');
}
</script>
<body>
<div>div</div>
<span>span</span>
</body>
或者将prevObject替换为end():
end: function() {
return this.prevObject || this.constructor(null);
},
$('div').pushStack($('span')).css('background-color','red').end().css('background-color','yellow');
pushStack: function( elems ) {
// Build a new jQuery matched element set
var ret = jQuery.merge( this.constructor(), elems );
// Add the old object onto the stack (as a reference)
ret.prevObject = this;
ret.context = this.context;
// Return the newly-formed element set
return ret;
},
constructor: jQuery,this.constructor()创建一个空的jQuery对象,
工具方法merge():第二个参数必须要有数值属性。else针对的是由数值属性,但没有length属性的情况
merge: function( first, second ) {
var l = second.length,
i = first.length,
j = 0;
if ( typeof l === "number" ) {
for ( ; j < l; j++ ) {
first[ i++ ] = second[ j ];
}
} else {
while ( second[j] !== undefined ) {
first[ i++ ] = second[ j++ ];
}
}
first.length = i;
return first;
},
<script>
window.onload = function(){
var test = document.getElementById('demo');
$('div').pushStack(test).css('background-color','red').end().css('background-color','yellow');
}
</script>
<body>
<div>div</div>
<span id="demo">span</span>
</body>
这是因为 test没有length属性,如果将test变成数组形式[test],就可以将span元素的背景显示红色
$('div').pushStack([test]).css('background-color','red').end().css('background-color','yellow');
$('div').get():将选中的原生元素存放到数组中,
$('div').get(num)当有参数时,返回对应下标的原生元素节点
$('xxx').slice() $('xxx').first() $('xxx').last() $('xxx').eq() $('xxx').map() $('xxx').end()返回的都是jQuery对象,且都利用了pushStack()方法,该方法的参数可以使jQuery对象,将选中的jQuery对象合并到新的空的jQuery对象中,新的jQuery对象的prevObject属性保存原先的jQuery对象
原生元素必须以数组元素的形式作为参数,因为要用到jQuery.merge()函数
jQuery.fn = jQuery.prototype = {
// The current version of jQuery being used
jquery: core_version,
constructor: jQuery,
toArray: function() {
return core_slice.call( this );
},
// Get the Nth element in the matched element set OR
// Get the whole matched element set as a clean array
get: function( num ) {
return num == null ?
// Return a 'clean' array
this.toArray() :
// Return just the object
( num < 0 ? this[ this.length + num ] : this[ num ] );
},
// Take an array of elements and push it onto the stack
// (returning the new matched element set)
pushStack: function( elems ) {
// Build a new jQuery matched element set
var ret = jQuery.merge( this.constructor(), elems );
// Add the old object onto the stack (as a reference)
ret.prevObject = this;
ret.context = this.context;
// Return the newly-formed element set
return ret;
},
// Execute a callback for every element in the matched set.
// (You can seed the arguments with an array of args, but this is
// only used internally.)
each: function( callback, args ) {
return jQuery.each( this, callback, args );
},
ready: function( fn ) {
// Add the callback
jQuery.ready.promise().done( fn );
return this;
},
slice: function() {
return this.pushStack( core_slice.apply( this, arguments ) );
},
first: function() {
return this.eq( 0 );
},
last: function() {
return this.eq( -1 );
},
eq: function( i ) {
var len = this.length,
j = +i + ( i < 0 ? len : 0 );
return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );
},
map: function( callback ) {
return this.pushStack( jQuery.map(this, function( elem, i ) {
return callback.call( elem, i, elem );
}));
},
end: function() {
return this.prevObject || this.constructor(null);
},
// For internal use only.
// Behaves like an Array's method, not like a jQuery method.
push: core_push,
sort: [].sort,
splice: [].splice
};