mirror of
https://github.com/jquery/jquery.git
synced 2024-11-23 02:54:22 +00:00
Reduce traversing module
This commit is contained in:
parent
c928ed432a
commit
65bdfbf07f
@ -12,12 +12,13 @@ var runtil = /Until$/,
|
|||||||
|
|
||||||
jQuery.fn.extend({
|
jQuery.fn.extend({
|
||||||
find: function( selector ) {
|
find: function( selector ) {
|
||||||
var i, ret, self;
|
var self, matched, i,
|
||||||
|
l = this.length;
|
||||||
|
|
||||||
if ( typeof selector !== "string" ) {
|
if ( typeof selector !== "string" ) {
|
||||||
self = this;
|
self = this;
|
||||||
return this.pushStack( jQuery( selector ).filter(function() {
|
return this.pushStack( jQuery( selector ).filter(function() {
|
||||||
for ( i = 0; i < self.length; i++ ) {
|
for ( i = 0; i < l; i++ ) {
|
||||||
if ( jQuery.contains( self[ i ], this ) ) {
|
if ( jQuery.contains( self[ i ], this ) ) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -25,24 +26,24 @@ jQuery.fn.extend({
|
|||||||
}) );
|
}) );
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = [];
|
matched = [];
|
||||||
for ( i = 0; i < this.length; i++ ) {
|
for ( i = 0; i < l; i++ ) {
|
||||||
jQuery.find( selector, this[ i ], ret );
|
jQuery.find( selector, this[ i ], matched );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Needed because $( selector, context ) becomes $( context ).find( selector )
|
// Needed because $( selector, context ) becomes $( context ).find( selector )
|
||||||
ret = this.pushStack( jQuery.unique( ret ) );
|
matched = this.pushStack( jQuery.unique( matched ) );
|
||||||
ret.selector = ( this.selector ? this.selector + " " : "" ) + selector;
|
matched.selector = ( this.selector ? this.selector + " " : "" ) + selector;
|
||||||
return ret;
|
return matched;
|
||||||
},
|
},
|
||||||
|
|
||||||
has: function( target ) {
|
has: function( target ) {
|
||||||
var i,
|
var targets = jQuery( target, this ),
|
||||||
targets = jQuery( target, this ),
|
l = targets.length;
|
||||||
len = targets.length;
|
|
||||||
|
|
||||||
return this.filter(function() {
|
return this.filter(function() {
|
||||||
for ( i = 0; i < len; i++ ) {
|
var i = 0;
|
||||||
|
for ( ; i < l; i++ ) {
|
||||||
if ( jQuery.contains( this, targets[i] ) ) {
|
if ( jQuery.contains( this, targets[i] ) ) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -64,33 +65,32 @@ jQuery.fn.extend({
|
|||||||
// If this is a positional/relative selector, check membership in the returned set
|
// If this is a positional/relative selector, check membership in the returned set
|
||||||
// so $("p:first").is("p:last") won't return true for a doc with two "p".
|
// so $("p:first").is("p:last") won't return true for a doc with two "p".
|
||||||
rneedsContext.test( selector ) ?
|
rneedsContext.test( selector ) ?
|
||||||
jQuery( selector, this.context ).index( this[0] ) >= 0 :
|
jQuery( selector, this.context ).index( this[ 0 ] ) >= 0 :
|
||||||
jQuery.filter( selector, this ).length > 0 :
|
jQuery.filter( selector, this ).length > 0 :
|
||||||
this.filter( selector ).length > 0 );
|
this.filter( selector ).length > 0 );
|
||||||
},
|
},
|
||||||
|
|
||||||
closest: function( selectors, context ) {
|
closest: function( selectors, context ) {
|
||||||
var cur,
|
var cur, i = 0,
|
||||||
i = 0,
|
|
||||||
l = this.length,
|
l = this.length,
|
||||||
ret = [],
|
matched = [],
|
||||||
pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
|
pos = ( rneedsContext.test( selectors ) || typeof selectors !== "string" ) ?
|
||||||
jQuery( selectors, context || this.context ) :
|
jQuery( selectors, context || this.context ) :
|
||||||
0;
|
0;
|
||||||
|
|
||||||
for ( ; i < l; i++ ) {
|
for ( ; i < l; i++ ) {
|
||||||
cur = this[i];
|
cur = this[ i ];
|
||||||
|
|
||||||
while ( cur && cur.ownerDocument && cur !== context && cur.nodeType !== 11 ) {
|
while ( cur && cur.ownerDocument && cur !== context ) {
|
||||||
if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {
|
if ( pos ? pos.index( cur ) > -1 : jQuery.find.matchesSelector( cur, selectors ) ) {
|
||||||
ret.push( cur );
|
matched.push( cur );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
cur = cur.parentNode;
|
cur = cur.parentElement;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.pushStack( ret.length > 1 ? jQuery.unique( ret ) : ret );
|
return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched );
|
||||||
},
|
},
|
||||||
|
|
||||||
// Determine the position of an element within
|
// Determine the position of an element within
|
||||||
@ -99,18 +99,20 @@ jQuery.fn.extend({
|
|||||||
|
|
||||||
// No argument, return index in parent
|
// No argument, return index in parent
|
||||||
if ( !elem ) {
|
if ( !elem ) {
|
||||||
return ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1;
|
return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// index in selector
|
// index in selector
|
||||||
if ( typeof elem === "string" ) {
|
if ( typeof elem === "string" ) {
|
||||||
return jQuery.inArray( this[0], jQuery( elem ) );
|
return core_indexOf.call( jQuery( elem ), this[ 0 ] );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Locate the position of the desired element
|
// Locate the position of the desired element
|
||||||
return jQuery.inArray(
|
return core_indexOf.call( this,
|
||||||
|
|
||||||
// If it receives a jQuery object, the first element is used
|
// If it receives a jQuery object, the first element is used
|
||||||
elem.jquery ? elem[0] : elem, this );
|
elem.jquery ? elem[ 0 ] : elem
|
||||||
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
add: function( selector, context ) {
|
add: function( selector, context ) {
|
||||||
@ -131,48 +133,42 @@ jQuery.fn.extend({
|
|||||||
|
|
||||||
jQuery.fn.andSelf = jQuery.fn.addBack;
|
jQuery.fn.andSelf = jQuery.fn.addBack;
|
||||||
|
|
||||||
function sibling( cur, dir ) {
|
|
||||||
do {
|
|
||||||
cur = cur[ dir ];
|
|
||||||
} while ( cur && cur.nodeType !== 1 );
|
|
||||||
|
|
||||||
return cur;
|
|
||||||
}
|
|
||||||
|
|
||||||
jQuery.each({
|
jQuery.each({
|
||||||
parent: function( elem ) {
|
parent: function( elem ) {
|
||||||
var parent = elem.parentNode;
|
return elem.parentElement;
|
||||||
return parent && parent.nodeType !== 11 ? parent : null;
|
|
||||||
},
|
},
|
||||||
parents: function( elem ) {
|
parents: function( elem ) {
|
||||||
return jQuery.dir( elem, "parentNode" );
|
return jQuery.dir( elem, "parentElement" );
|
||||||
},
|
},
|
||||||
parentsUntil: function( elem, i, until ) {
|
parentsUntil: function( elem, i, until ) {
|
||||||
return jQuery.dir( elem, "parentNode", until );
|
return jQuery.dir( elem, "parentElement", until );
|
||||||
},
|
},
|
||||||
next: function( elem ) {
|
next: function( elem ) {
|
||||||
return sibling( elem, "nextSibling" );
|
return elem.nextElementSibling;
|
||||||
},
|
},
|
||||||
prev: function( elem ) {
|
prev: function( elem ) {
|
||||||
return sibling( elem, "previousSibling" );
|
return elem.previousElementSibling;
|
||||||
},
|
},
|
||||||
nextAll: function( elem ) {
|
nextAll: function( elem ) {
|
||||||
return jQuery.dir( elem, "nextSibling" );
|
return jQuery.dir( elem, "nextElementSibling" );
|
||||||
},
|
},
|
||||||
prevAll: function( elem ) {
|
prevAll: function( elem ) {
|
||||||
return jQuery.dir( elem, "previousSibling" );
|
return jQuery.dir( elem, "previousElementSibling" );
|
||||||
},
|
},
|
||||||
nextUntil: function( elem, i, until ) {
|
nextUntil: function( elem, i, until ) {
|
||||||
return jQuery.dir( elem, "nextSibling", until );
|
return jQuery.dir( elem, "nextElementSibling", until );
|
||||||
},
|
},
|
||||||
prevUntil: function( elem, i, until ) {
|
prevUntil: function( elem, i, until ) {
|
||||||
return jQuery.dir( elem, "previousSibling", until );
|
return jQuery.dir( elem, "previousElementSibling", until );
|
||||||
},
|
},
|
||||||
siblings: function( elem ) {
|
siblings: function( elem ) {
|
||||||
return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );
|
return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );
|
||||||
},
|
},
|
||||||
children: function( elem ) {
|
children: function( elem ) {
|
||||||
return jQuery.sibling( elem.firstChild );
|
var children = elem.children;
|
||||||
|
|
||||||
|
// documentFragment or document does not have children property
|
||||||
|
return children ? jQuery.merge( [], children ) : jQuery.sibling( elem.firstChild );
|
||||||
},
|
},
|
||||||
contents: function( elem ) {
|
contents: function( elem ) {
|
||||||
return jQuery.nodeName( elem, "iframe" ) ?
|
return jQuery.nodeName( elem, "iframe" ) ?
|
||||||
@ -181,23 +177,27 @@ jQuery.each({
|
|||||||
}
|
}
|
||||||
}, function( name, fn ) {
|
}, function( name, fn ) {
|
||||||
jQuery.fn[ name ] = function( until, selector ) {
|
jQuery.fn[ name ] = function( until, selector ) {
|
||||||
var ret = jQuery.map( this, fn, until );
|
var matched = jQuery.map( this, fn, until );
|
||||||
|
|
||||||
if ( !runtil.test( name ) ) {
|
if ( !runtil.test( name ) ) {
|
||||||
selector = until;
|
selector = until;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( selector && typeof selector === "string" ) {
|
if ( selector && typeof selector === "string" ) {
|
||||||
ret = jQuery.filter( selector, ret );
|
matched = jQuery.filter( selector, matched );
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret;
|
if ( this.length > 1 ) {
|
||||||
|
if ( !guaranteedUnique[ name ] ) {
|
||||||
if ( this.length > 1 && rparentsprev.test( name ) ) {
|
jQuery.unique( matched );
|
||||||
ret = ret.reverse();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.pushStack( ret );
|
if ( rparentsprev.test( name ) ) {
|
||||||
|
matched.reverse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.pushStack( matched );
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -208,33 +208,32 @@ jQuery.extend({
|
|||||||
}
|
}
|
||||||
|
|
||||||
return elems.length === 1 ?
|
return elems.length === 1 ?
|
||||||
jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :
|
jQuery.find.matchesSelector( elems[ 0 ], expr ) ? [ elems[ 0 ] ] : [] :
|
||||||
jQuery.find.matches(expr, elems);
|
jQuery.find.matches( expr, elems );
|
||||||
},
|
},
|
||||||
|
|
||||||
dir: function( elem, dir, until ) {
|
dir: function( elem, dir, until ) {
|
||||||
var matched = [],
|
var cur = elem[ dir ],
|
||||||
cur = elem[ dir ];
|
matched = [];
|
||||||
|
|
||||||
while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
|
while ( cur && ( !until || !jQuery( cur ).is( until ) ) ) {
|
||||||
if ( cur.nodeType === 1 ) {
|
|
||||||
matched.push( cur );
|
matched.push( cur );
|
||||||
|
cur = cur[ dir ];
|
||||||
}
|
}
|
||||||
cur = cur[dir];
|
|
||||||
}
|
|
||||||
return matched;
|
return matched;
|
||||||
},
|
},
|
||||||
|
|
||||||
sibling: function( n, elem ) {
|
sibling: function( n, elem ) {
|
||||||
var r = [];
|
var matched = [];
|
||||||
|
|
||||||
for ( ; n; n = n.nextSibling ) {
|
for ( ; n; n = n.nextSibling ) {
|
||||||
if ( n.nodeType === 1 && n !== elem ) {
|
if ( n.nodeType === 1 && n !== elem ) {
|
||||||
r.push( n );
|
matched.push( n );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return r;
|
return matched;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -245,30 +244,34 @@ function winnow( elements, qualifier, keep ) {
|
|||||||
// Set to 0 to skip string check
|
// Set to 0 to skip string check
|
||||||
qualifier = qualifier || 0;
|
qualifier = qualifier || 0;
|
||||||
|
|
||||||
|
var filtered;
|
||||||
|
|
||||||
if ( jQuery.isFunction( qualifier ) ) {
|
if ( jQuery.isFunction( qualifier ) ) {
|
||||||
return jQuery.grep(elements, function( elem, i ) {
|
return jQuery.grep(elements, function( elem, i ) {
|
||||||
var retVal = !!qualifier.call( elem, i, elem );
|
var retVal = !!qualifier.call( elem, i, elem );
|
||||||
return retVal === keep;
|
return retVal === keep;
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
} else if ( qualifier.nodeType ) {
|
if ( qualifier.nodeType ) {
|
||||||
return jQuery.grep(elements, function( elem ) {
|
return jQuery.grep(elements, function( elem ) {
|
||||||
return ( elem === qualifier ) === keep;
|
return ( elem === qualifier ) === keep;
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
} else if ( typeof qualifier === "string" ) {
|
if ( typeof qualifier === "string" ) {
|
||||||
var filtered = jQuery.grep(elements, function( elem ) {
|
filtered = jQuery.grep(elements, function( elem ) {
|
||||||
return elem.nodeType === 1;
|
return elem.nodeType === 1;
|
||||||
});
|
});
|
||||||
|
|
||||||
if ( isSimple.test( qualifier ) ) {
|
if ( isSimple.test( qualifier ) ) {
|
||||||
return jQuery.filter(qualifier, filtered, !keep);
|
return jQuery.filter( qualifier, filtered, !keep );
|
||||||
} else {
|
|
||||||
qualifier = jQuery.filter( qualifier, filtered );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qualifier = jQuery.filter( qualifier, filtered );
|
||||||
}
|
}
|
||||||
|
|
||||||
return jQuery.grep(elements, function( elem ) {
|
return jQuery.grep(elements, function( elem ) {
|
||||||
return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep;
|
return ( core_indexOf.call( qualifier, elem ) >= 0 ) === keep;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -658,10 +658,15 @@ test("eq('-1') #10616", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("index(no arg) #10977", function() {
|
test("index(no arg) #10977", function() {
|
||||||
expect(1);
|
expect(2);
|
||||||
|
|
||||||
var $list = jQuery("<ul id='indextest'><li>THIS ONE</li><li class='one'>a</li><li class='two'>b</li><li class='three'>c</li></ul>");
|
var $list = jQuery("<ul id='indextest'><li>THIS ONE</li><li class='one'>a</li><li class='two'>b</li><li class='three'>c</li></ul>");
|
||||||
jQuery("#qunit-fixture").append( $list );
|
jQuery("#qunit-fixture").append( $list );
|
||||||
strictEqual ( jQuery( "#indextest li:not(.one,.two)" ).index() , 0, "No Argument Index Check" );
|
strictEqual ( jQuery( "#indextest li:not(.one,.two)" ).index() , 0, "No Argument Index Check" );
|
||||||
$list.remove();
|
$list.remove();
|
||||||
|
|
||||||
|
var fragment = document.createDocumentFragment(),
|
||||||
|
div = fragment.appendChild( document.createElement("div") );
|
||||||
|
|
||||||
|
equal( jQuery( div ).index(), 0, "If jQuery#index called on element whos parent is fragment, it still should work correctly" );
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user