HTML code, test address: jQuery traversal - closest() method
------I paste the code and it will be automatically hidden on the page (it will be displayed)! Can anyone teach me what's going on?
1. Find level-3 through item-1 (find direct superior)
$('li.item-1').closest('ul')
$('li.item-1').parent()
$('li.item- 1').parents().eq(0)
2. Find level-2 through item-1 (find the parent element through the selector)
$('li.item-1').closest('.level-2')
//$('li.item-1').parent('.level-2') //Cannot be found, the parent() method only traverses to the previous level!
$('li.item-1').parent().parent() //This is too weird!
$('li.item-1').parents('.level-2')
Usage of selector in parent(selector)
$('li').parent() //Return level-3, level-2 and level -1 collection, they are all parent elements of li
$('li').parent('.level-3') //Filter out level-3 in the above collection
3.The closest method starts traversing from the current element, while parent() starts from the parent element!
$('li.item-1').closest('li') //Return item-1. Please pay attention when using it. If a div is nested in a div, you must consider the correctness of the selector. use!
4. Usage of the context parameter in closet(selector,context) Traverse from the current element to the end of the context element. If there is no context parameter, traverse to the root node
It can be seen that using the context parameter can improve query efficiency!
var listItemII = document.getElementById('ii'); //Item-II
//var listItemII=$('#ii'), this doesn’t work, I was confused for a long time!
$('li.item-1').closest('ul', listItemII).css('background-color', 'red');
//The result must be the parent of item-1 ul element, sub-element of itemII,
$('li.item-1').closest('#one', listItemII).css('background-color', 'green');
// The element with id=one of item-1 must be a child element of itemII.
5. Analysis of context parameter is not found
closest: function( selectors, context ) {
var ret = [], i, l, cur = this[0 ];
// String
var pos = POS.test( selectors ) || typeof selectors !== "string" ?
jQuery( selectors, context || this.context ) :
0 ;
for ( i = 0, l = this.length; i < l; i ) {
cur = this[i];
while ( cur ) {
if ( pos ? pos .index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {
//If a matching element is found, add it to the return value collection! Jump to the search for the next element
ret.push( cur );
break;
} else {
cur = cur.parentNode;
//Traverse up the DOM tree and match the selector
//In the above process, if the parent node does not exist, the root node does not exist or the context node is found (the specified position has been reached)!
if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) {
break;
}
}
}
}
ret = ret.length > 1 ? jQuery.unique( ret ) : ret;
return this.pushStack( ret, "closest", selectors );
}
I don’t know much about the JQuery source code, so I won’t explain some of the details!
From the definition of closest(), we can know that the variable cur=this[i] compared with context is a DOM object, and the $('#ii') method gets a JQuery object, so it is passed to closest The context parameter of the (selector, context) method must be obtained through the DOM method!
Conversion of jQuery objects and DOM objects?
1. Get the object (the purpose of adding $ before the variable name is to distinguish JQuery and DOM variables):
Get the jQuery object: var $variable=jQuery object;
Get the DOM object: var variable=DOM object;
2.jQuery object to DOM object:
Use array to convert var cr=$("#cr")[0];
Use get(index) method to convert var cr=$("#cr") .get(0);
3. Convert DOM object to jQuery object:
var cr=document.getElementsById("cr"); //Get the DOM object
var $cr=$(cr);//Convert to jQuery object
SO ….
$('li.item-1').closest('#one', $('#ii').get(0))//Use
like this or put "cur= in the source code The judgment of ==context" is changed to "$(cur)====$(current)", so that the two usages can be compatible!
Of course, modifying the source code is not a good suggestion, but why does JQuery itself not use this method... Please give me some advice! ! !