「も〜、、、 何回同じこと調べるねん!」
ということで、自分のためにも覚書です。
「find()
とfilter()
ってどう違うんだっけ?」
「closest()
ってセレクタ自身も取得対象に含んでたっけ?」
この曖昧な記憶をスッキリさせたいと思います。
find()・children()・closest()・parent()・parents()・filter()それぞれの違いと使い方
セレクタ付近の要素を取得するために使うjQueryのメソッドは、大きく分けて
① 子・孫要素を取得するメソッド
② 親・祖先要素を取得するメソッド
③ 指定した選択肢の中でフィルタリングをかけて取得するメソッド
の3つに分類できるかと思います。
① 子・孫要素を取得するメソッド
1. find()
指定した要素よりも中の要素から、条件にマッチする全ての子孫要素を取得します。
<div class="parent">
<div class="child active">子要素</div>
<div class="child">
<div class="grandchild">孫要素</div>
</div>
</div>
以下は、parentクラス要素の全ての子孫要素の中から、activeクラスを持つ要素を取得する場合。1つ目の子要素が取れています。
$('.parent').find('.active').css('background-color', 'yellow');
次は、parentクラス要素の全ての子孫要素の中からchildクラスを持つ要素を探す場合。
find()
は条件にマッチする全ての子孫要素を取得するので、<div class="child active">子要素</div>
と、<div class="child"><div class="grandchild">孫要素</div></div>
の2つが取れています。
$('.parent').find('.child').css('background-color', 'yellow');
そして、parentクラスの中でgrandchildクラスを持つ要素を探す場合。子要素より下の階層にある孫要素も取得できています。
$('.parent').find('.grandchild').css('background-color', 'yellow');
2. children()
children()
は、指定した要素の直下の子要素だけを取得するメソッドです。
直下の子要素だけを対象にするので、孫要素やそれ以上の深さの要素を取得できない点でfind()
とは異なります。
$('.parent').children('.child').css('background-color', 'yellow');
上のように、子要素は問題なく取得できるのですが、
$('.parent').children('.grandchild').css('background-color', 'yellow');
としても、直下の子要素にgrandchildクラスは存在しないので、要素を見つけることができません。
② 親・祖先要素を取得するメソッド
1. parent()
parent()
は、指定した要素の直近の親要素だけを取得するメソッドです。
<div class="grandparent active">祖先要素
<div class="parent active">親要素
<div class="child">子要素</div>
</div>
</div>
$('.child').parent('div').css('border', '5px solid red');
今度は、取得できた要素に赤枠をつけています。childクラスの直近の親要素のdivタグは<div class="parent active">
なので、そのエリアに赤枠がつきました。
直近の階層しか取得できないという意味ではchildren()
と対になるメソッドです。ただ、1つの親要素に対して複数の子要素が存在しうるのに対し、1つの子要素に親は1つなので、原則、指定した要素の数だけの要素がparent()
の取得できる選択肢になるという点でやや異なります。
2. parents()
parents()
は、指定した要素の全ての祖先要素が取得範囲になります。今度は親より遠い祖先も取得範囲になり、「全て」取得できるので、複数形になるんですね。
$('.child').parents('div').css('border', '5px solid red');
childクラス要素の親以上に当たるdivタグは<div class="parent active">
と<div class="grandparent active">
の2つなので、二重に赤枠がついています。
3. closest()
closest()
は、指定した要素から見て、最も近い祖先要素を探索し、条件に一致する最初の要素を選択します。
$('.child').closest('div').css('border', '5px solid red');
ここで、parent()
やparents()
と違うのは、取得の選択肢に自身も含むということ。
親方向に2階層以上遡れるという意味ではparentsと似ていて、条件を満たす1つを取得するという意味ではparentと同じですが、自身が条件に一致する場合、自身を選ぶことができます。自身が条件に合わない場合は、順に祖先を辿り、一番最初にマッチするものを取得します。
なので、例えば以下のようにすると、親以上の中で一番近いactiveクラスの要素を取得するので、
$('.child').closest('.active').css('border', '5px solid red');
と、直近の親要素を取得します。
これが、parents()
に置き換えると、親以上のactiveクラスを持つ要素全てが取得できるので、親要素と祖先要素の周りに二重に枠がつくというわけです。
③ "ちょっと異質" 指定した選択肢の中でフィルタリングをかける filter()
メソッド
filter()
は、自分で指定した選択肢の中から、指定した条件にマッチする要素だけを取得するメソッドです。
私の認識としては、その名の通り、「フィルター」。
絞り込みで要素を探していくイメージです。指定した要素の内、条件に当てはまるものを探します。親子関係や個数は関係ありません。とにかくフィルターに引っかかりさえすれば良いのです。
<div class="container">
<ul>
<li class="item">Item 1</li>
<li class="item">Item 2</li>
<li class="item active">Item 3</li>
<li class="item">Item 4</li>
</ul>
</div>
$('li').filter('.active').css('background-color', 'yellow');
この場合、liタグ全て(4つ)を選択肢として指定して、その中でactiveクラスであるという条件を満たすものが取得できます。
つまり、以下のようにitemクラスであることを取得の条件にすれば、全てのliタグが条件を満たすので、4つとも取得されます。
$('li').filter('.item').css('background-color', 'yellow');
逆にfilter()
のセレクタにulを指定してしまうと、itemクラスを満たすulタグはないので、もちろん何も取得できません。
$('ul').filter('.item').css('background-color', 'yellow');
子孫取得系とfilter()、ちょっとややこしい。 違いを整理
個人的にやや混乱したことを整理して以下にまとめます。主に、filter()
とfind()
、children()
って具体的にどう違う?というお話です。
先ほどの例で、liタグの内からitemクラスを検索すると、itemクラスである要素が全て取れました。
$('li').filter('.item').css('background-color', 'yellow');
しかし、この指定方法はfind()
だと機能しません。find()
は自分より中の階層にいる子孫要素しか対象にならないので、find()
のセレクタにliタグを指定した時点で、liタグ要素を取得することはできないのです。
$('li').find('.item').css('background-color', 'yellow');
find()
で同様にitemクラスを探したいなら、ひとつ上(親)のulタグを指定するとOKです。
$('ul').find('.item').css('background-color', 'yellow');
ちなみに以下にしても結果は同じです。find()
は孫以下も取得対象でしたね。
$('.container').find('.item').css('background-color', 'yellow');
ただし、children()
は違います。直下の子要素しか取得できません。containerクラスの直下の子要素はulタグになるので、liタグを取得できないのです。
$('.container').children('.item').css('background-color', 'yellow');
children()
でliタグのitemクラス要素を取得したいなら、直近の親要素であるulタグをセレクタに指定する必要があります。
$('ul').children('.item').css('background-color', 'yellow');
無事取得できました。以上、混乱しそうなパターンを記してみました。
まとめ
メソッド | 検索対象 | 結果 |
---|---|---|
find() | 全ての子孫要素 | 子孫要素の中から条件にマッチする要素全て |
children() | 直下の子要素のみ | 条件にマッチする直下の子要素全て |
parent() | 直近の親要素のみ | 条件にマッチする直近の親要素 |
parents() | 全ての祖先要素(自身は含まない) | 祖先要素の中から条件にマッチする要素全て |
closest() | 全ての祖先要素(自身含む) | 指定した要素から見て、条件にマッチする最初の(=自身から一番近い)要素 |
filter() | 指定した要素 | 条件にマッチする要素全て |
p.s.
これでしばらくは「 find() filter() 違い 」と、Google先生に何度も同じことを聞かなくて済みそうです。