jQueryソース分析のparents,parentsUntil,next,prev,nextAll,prevAll,nextUntil,prevUntil,siblings,children
8306 ワード
parents,parentsUntil,next,prev,nextAll,prevAll,nextUntil,prevUntil,siblings,children,contentsこれらのインスタンス関数を抽出してテストします.ソースコードは次のとおりです.
jQuery.dirメソッド:
jQuery.Siblingsメソッドソース:(2番目のパラメータは終了パラメータ)
Siblingメソッド:
parentsメソッドソース:
注意:他の接尾辞はuntilの方法ではなく、selectorが選択した結果を選択することを示すパラメータしか入力できません.ここのjQuery.mapは3番目のパラメータを入力し、その中のfnは3つのパラメータを入力します.それぞれ、DOM要素、DOM要素の下付き、余分なuntilパラメータはprevUntilなどのuntilメソッドに使用され、検索を停止するフラグとして使用されます.
直接親要素
jQuery.Siblingsは、すべての兄弟要素を取得するために使用されます.
childrenメソッドは、エレメントのすべてのサブエレメントを取得しますが、Elementタイプのエレメントのみが含まれます.
childNodes集合
私たちが呼び出すとき、この方法にパラメータを入力するだけであれば、このパラメータはuntilであり、2つのパラメータを入力する最初のパラメータがuntilであれば、2番目のパラメータがselectorであり、つまりuntilタイプの方法の最初のパラメータは必ずuntilである!
parentUtil指定した要素の最後まですべての親要素を取得
まとめ:
(1)parents等の方法は、まず、各呼び出しオブジェクトのDOMオブジェクトに対して対応するdir又はsiblingsメソッドを呼び出し、結果配列を得る.次にparentsなどの方法のパラメータをセレクタとして結果配列をフィルタリングし,有効な結果を得た!parentsUtilsでは、2番目のパラメータutilが入力される可能性があります.dirメソッドでは、そのutilパラメータに対してparentNodeの移動を終了し、返された結果を最初のパラメータで再計算します.考え方:先に選んでからやり直す
(2)nextUtilなどが1つのパラメータだけを入力した場合、このパラメータはuntilであり、2つのパラメータを入力した場合、最初のパラメータはuntilであり、2番目のパラメータはselectorであり(つまり、この場合はUntilがあることを示している場合、最初のパラメータは必ずuntilである)、前のステップで選択した結果をさらにフィルタするために使用される!untilタイプでない場合は、selectorというパラメータが1つしか入力されません.
(3)untilのときに入ってきた3番目のパラメータがそのままコールバック関数に入ってくることがわかりますので、jQueryオブジェクトではなくDOMオブジェクトであることに注意してください
jQuery.dirメソッド:
dir: function( elem, dir, until ) {
//
var matched = [],
cur = elem[ dir ];
// nextUntil until, parents , parents . until undefined, parentNode
// jQuery
// until , !
while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
if ( cur.nodeType === 1 ) {
matched.push( cur );
}
cur = cur[dir];
}
return matched;
}
jQuery.Siblingsメソッドソース:(2番目のパラメータは終了パラメータ)
sibling: function( n, elem ) {
var r = [];
for ( ; n; n = n.nextSibling ) {
if ( n.nodeType === 1 && n !== elem ) {
r.push( n );
}
}
return r;
}
Siblingメソッド:
function sibling( cur, dir ) {// next/pre , sibling(elem,"previousSibling")
do {
cur = cur[ dir ];
} while ( cur && cur.nodeType !== 1 );
return cur;
}
parentsメソッドソース:
jQuery.each({
parent: function( elem ) {
var parent = elem.parentNode;
return parent && parent.nodeType !== 11 ? parent : null;
},
//dir parentNode, var $parents3 = $p.parents(".bar");
// parents $p DOM $p[i], until arguments[1]
// $p.parents(".bar"); until ".bar" arguments[1] ".bar"
parents: function( elem ) {
return jQuery.dir( elem, "parentNode" );
},
parentsUntil: function( elem, i, until ) {
return jQuery.dir( elem, "parentNode", until );
},
next: function( elem ) {
return sibling( elem, "nextSibling" );
},
prev: function( elem ) {
return sibling( elem, "previousSibling" );
},
nextAll: function( elem ) {
return jQuery.dir( elem, "nextSibling" );
},
prevAll: function( elem ) {
return jQuery.dir( elem, "previousSibling" );
},
//nextUntil , $p[i], DOM ,util
nextUntil: function( elem, i, until ) {
return jQuery.dir( elem, "nextSibling", until );
},
//prevUntil
prevUntil: function( elem, i, until ) {
return jQuery.dir( elem, "previousSibling", until );
},
siblings: function( elem ) {
return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );
},
children: function( elem ) {
return jQuery.sibling( elem.firstChild );
},
contents: function( elem ) {
return jQuery.nodeName( elem, "iframe" ) ?
elem.contentDocument || elem.contentWindow.document :
jQuery.merge( [], elem.childNodes );
}
}, function( name, fn ) {
//jQuery.fn[ "parents"] , 。 $p.parents(".bar");
jQuery.fn[ name ] = function( until, selector ) {
/* $p fn , parents , Array ,until , ".bar"。 this $p, fn, parents , this[i], DOM , parents DOM 。 fn DOM , $.map , fn , , jQuery.map 。 fn true, ret 。*/
var ret = jQuery.map( this, fn, until );
// parentsUntil , , selector until, ".bar"
// parentsUtil , until, until ,dir
if ( name.slice( -5 ) !== "Until" ) {
selector = until;
}
// selector , selector ret !
if ( selector && typeof selector === "string" ) {
ret = jQuery.filter( selector, ret );
}
// $p 1, $p[0],$p[i] !
if ( this.length > 1 ) {
// Remove duplicates
if ( !guaranteedUnique[ name ] ) {
ret = jQuery.unique( ret );
}
// Reverse order for parents* and prev-derivatives</span>
//var rparentsprev = /^(?:parents|prev(?:Until|All))/,</span>
// parents,prev
if ( rparentsprev.test( name ) ) {
ret = ret.reverse();
}
}
return this.pushStack( ret );
};
});
注意:他の接尾辞はuntilの方法ではなく、selectorが選択した結果を選択することを示すパラメータしか入力できません.ここのjQuery.mapは3番目のパラメータを入力し、その中のfnは3つのパラメータを入力します.それぞれ、DOM要素、DOM要素の下付き、余分なuntilパラメータはprevUntilなどのuntilメソッドに使用され、検索を停止するフラグとして使用されます.
next: function( elem ) {
return sibling( elem, "nextSibling" );
}
nextは呼び出しオブジェクトのすべての次の同級のオブジェクトからなる集合を取得し、なぜすべてのDOMの次の兄弟ノードをjQueryから真の集合を構成することができるのか.mapの役割.実は各DOMの次の兄弟ノードを巡るときに返されるのは配列で、jQuery.mapで[]が呼び出された.concat.apply([],ret); nextAll: function( elem ) {
return jQuery.dir( elem, "nextSibling" );
}
nextで呼び出されたsiblingsは、同じ方向の要素のみを取得する方法です.nextAllが呼び出したのはjQueryですdir、彼は指定した方向のすべての要素を取得して、untilが終わることを知っていますfunction sibling( cur, dir ) {// next/pre , sibling(elem,"previousSibling")
do {
cur = cur[ dir ];
} while ( cur && cur.nodeType !== 1 );
return cur;
}
prevメソッドは、指定された方向の要素を取得し、呼び出された要素は依然としてsiblingsメソッドである.prev: function( elem ) {
return sibling( elem, "previousSibling" );
}
prevAllがjQueryを呼び出す.dir,この方法は同方向のすべての要素を取得するprevAll: function( elem ) {
return jQuery.dir( elem, "previousSibling" );
}
parent要素取得直接親要素
parent: function( elem ) {
var parent = elem.parentNode;
return parent && parent.nodeType !== 11 ? parent : null;
}
でparentsはjQueryを使用しています.dir指定した方向のすべての要素を取得parents: function( elem ) {
return jQuery.dir( elem, "parentNode" );
}
nextall同方向のすべての要素を取得nextAll: function( elem ) {
return jQuery.dir( elem, "nextSibling" );
}
jQuery.Siblingsは、すべての兄弟要素を取得するために使用されます.
sibling: function( n, elem ) {
var r = [];
for ( ; n; n = n.nextSibling ) {
if ( n.nodeType === 1 && n !== elem ) {//
r.push( n );
}
}
return r;
}
siblingsメソッドを見てみましょう siblings: function( elem ) {
return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );
}
この関数は自分自身を返さないで、ただ自分のすべての同級要素を返します!childrenメソッドは、エレメントのすべてのサブエレメントを取得しますが、Elementタイプのエレメントのみが含まれます.
children: function( elem ) {
return jQuery.sibling( elem.firstChild );
}
contentsインスタンスメソッドiframeならcontentWindowを取得する.documentまたはcontentDocument.iframeでなければ結果にはすべてが含まれますchildNodes集合
contents: function( elem ) {
return jQuery.nodeName( elem, "iframe" ) ?
elem.contentDocument || elem.contentWindow.document :
jQuery.merge( [], elem.childNodes );
}
すべてのuntilの末尾の要素に対してjQuery.dirは、3番目のパラメータが検索を終了する要素を表す.私たちが呼び出すとき、この方法にパラメータを入力するだけであれば、このパラメータはuntilであり、2つのパラメータを入力する最初のパラメータがuntilであれば、2番目のパラメータがselectorであり、つまりuntilタイプの方法の最初のパラメータは必ずuntilである!
parentUtil指定した要素の最後まですべての親要素を取得
parentsUntil: function( elem, i, until ) {
return jQuery.dir( elem, "parentNode", until );
}
prevUtil指定された要素まですべての兄弟要素を取得prevUntil: function( elem, i, until ) {
return jQuery.dir( elem, "previousSibling", until );
}
nextUtil特定のエレメントが終了するまで、指定した兄弟エレメントを取得nextUntil: function( elem, i, until ) {
return jQuery.dir( elem, "nextSibling", until );
}
まとめ:
(1)parents等の方法は、まず、各呼び出しオブジェクトのDOMオブジェクトに対して対応するdir又はsiblingsメソッドを呼び出し、結果配列を得る.次にparentsなどの方法のパラメータをセレクタとして結果配列をフィルタリングし,有効な結果を得た!parentsUtilsでは、2番目のパラメータutilが入力される可能性があります.dirメソッドでは、そのutilパラメータに対してparentNodeの移動を終了し、返された結果を最初のパラメータで再計算します.考え方:先に選んでからやり直す
(2)nextUtilなどが1つのパラメータだけを入力した場合、このパラメータはuntilであり、2つのパラメータを入力した場合、最初のパラメータはuntilであり、2番目のパラメータはselectorであり(つまり、この場合はUntilがあることを示している場合、最初のパラメータは必ずuntilである)、前のステップで選択した結果をさらにフィルタするために使用される!untilタイプでない場合は、selectorというパラメータが1つしか入力されません.
(3)untilのときに入ってきた3番目のパラメータがそのままコールバック関数に入ってくることがわかりますので、jQueryオブジェクトではなくDOMオブジェクトであることに注意してください
var result=$("#n7").prevUntil($('#n5')[0]);//DOM
console.log(result);