こんにちは、ライターのマサトです!
今回は、jQueryで効率よく親要素を取得することができる「closest()」メソッドについて学習していきましょう!
この記事では、
・「closest」とは?
・「closest」の使い方
という基本的な内容から、
・「tr」を使ったTable要素の取得方法
・「closest」の戻り値
・「closest」と「parent」の違い
・「closest」と「find」の違い
などの応用的な使い方に関しても解説していきます。
この記事で、jQueryによる「closest()」をしっかり学習して自分のスキルアップを目指しましょう!
「closest」とは?
それでは、まず最初に「closest()」メソッドについての基本的な知識から勉強を進めていきましょう!
「closest()」は、基本的に親要素を取得することができるメソッドです。
ただし、検索性と高速性を兼ね備えているのが特徴で、指定した「タグ・属性」を持つ親要素を瞬時に探し出せるのです。
例えば、次のようなHTMLがあったとします。
<div class="wrap"> <div class="contents"> <div class="main"> <p id="text">サンプルテキスト</p> </div> </div> </div>
このHTMLでは、p要素が3つのdivタグの中に配置されています。
例えば、p要素がクラス名「contents」を付与された親要素の中にあるかどうか?…を知りたい時にどうすれば良いでしょうか?
ここで最も簡単で素早く知る方法として「closest()」メソッドを使うわけですね。
本記事では、この「closest()」メソッドについてさまざまな活用例を解説していきますのでぜひ参考にしてみてください!
「closest」の使い方
この章では、「closest」の基本的な使い方について見ていきましょう!
直近の親要素を取得する方法や、クラス属性・検索範囲の指定などの使い方について学んでいきます。
直近の親要素を「closest」で取得する
それでは、「closest()」メソッドの具体的な使い方を学んでいきましょう!
一般的な記述方法としては、【要素.closest(セレクタ)】のように対象要素へセレクタ指定すればOKです。
次のサンプル例を見てください!
<body> <div class="wrap"> <ul> <li>項目1</li> <li>項目2</li> <li>項目3</li> </ul> </div> <script> var result = $('li').closest('div'); console.log( result ); </script> </body>
実行結果
[div.wrap, ......]
この例では、div要素内にリスト項目が配置されているのが分かります。
このli要素に対して、「.closest(‘div’)」と記述することで親要素に「div要素」があるかどうかをチェックできます。
実行結果を見ると、しっかりとdiv要素を取得できているのが分かりますね。
注意点としては、li要素から最も近い場所にある対象のdiv要素だけを取得するという点です!
つまり、親要素としてdivタグが複数あったとしても、最初に合致したdiv要素だけを取得するので覚えておきましょう!
クラス(class)を使って直近の親要素を取得する
先ほどは「closest()」の引数にdivタグを指定しましたが、今度はよく使われるクラスを指定してみましょう!
考え方はまったく同じで、closest()のセレクタ指定をクラスにするだけです。
次のサンプル例を見てください!
<body> <div id="wrap" class="contents"> <div class="contents"> <div class="main"> <p id="text">サンプルテキスト</p> </div> </div> </div> <script> var result = $('p').closest('.contents'); console.log( result ); </script> </body>
実行結果
[div.contents, ......]
この例では、3つのdivタグに囲まれたp要素が配置されていますね。
このp要素に対して「closest(‘.contents’)」と記述することで、クラス名「contents」が付与された親要素を取得できます。
ただし、クラス名「contents」が付与された親要素はよく見ると2つ存在していますよね?
しかし、p要素から最も近い場所にある親要素(divタグ)だけを取得しているのがポイントです。
一番外側にあるdiv要素は該当しないので注意しましょう。
検索範囲を指定して直近の親要素を取得する
「closest()」は親要素を検索する範囲を意図的に指定することも可能なのでご紹介しておきます!
これまでは【closest(セレクタ)】のように記述してきましたが、実は第2引数にDOM要素を指定することができます。
【closest(セレクタ, 任意のDOM要素】のように記述し、第2引数で指定したDOM要素内を範囲として決めることができるわけです。
次のサンプル例を見てください!
<body> <div class="wrap"> <div id="main"> <div> <p>サンプルテキスト</p> </div> </div> </div> <script> var result = $('p').closest('.wrap'); console.log( result ); </script> </body>
実行結果
[div.wrap, ......]
この例では、3つのdivタグに囲まれたP要素が配置されています。
このP要素に対して「closest(‘.wrap’)」と記述することで、一番外側のdiv要素を取得することができますよね。
ここで、第2引数を指定して範囲を決めてみましょう!
var main = document.getElementById('main'); var result = $('p').closest('.wrap', main); console.log( result );
まず最初に、id属性値「main」を持つDOM要素を「getElementById()」を使って取得します。
それを「closest()」メソッドの第2引数へ指定するわけです。
すると、先ほどは一番外側のdivタグが取得できていたのに今度は取得できません。
なぜなら、検索範囲がid属性値「main」を持つdivタグ内に変更されているからですね。
このように、意図的に範囲を決めることでより効率よく特定の親要素を取得できるようになるので覚えておきましょう!
「tr」を使ったTable要素の取得方法
今度はTable要素における「closest()」の使い方について見ていきましょう!
基本的な考え方はこれまでと同じなのですが、例えば「tr要素」を親に持つ「td要素」にclosest()を使ってみましょう。
次のようなテーブルのHTMLを想定してください。
<body> <table> <tr class="one"> <td>セル1</td> <td class="select">セル2</td> <td>セル3</td> </tr> <tr class="two"> <td>セル4</td> <td>セル5</td> <td>セル6</td> </tr> </table> </body>
この例では、2行×3列のシンプルなテーブル要素が配置されています。
このようなテーブル要素に対して、例えばclass属性値「select」が付与された「td要素」の親要素を取得してみましょう!
var tr = $('.select').closest('tr'); console.log( tr );
実行結果
[tr.one, ......]
td要素に対して「closest(‘tr’)」と記述することで、その親要素である「tr要素」が取得できますね。
ただし、今回のように「td」の親要素は「tr」と決まっている場合は「parent()」を使っても良いでしょう。
var tr = $('.select').parent('tr'); console.log( tr );
実行結果
[tr.one, ......]
このように、「parent()」メソッドを使っても結果は同じになります。
「closest」の戻り値
この章では、「closest」の戻り値について詳しく見ていきましょう!
基本的な戻り値を取得する方法から、条件分岐処理に活用する方法までを学んでいきます。
戻り値「length」を取得する方法
ここまで「closest()」で親要素を取得する方法について見てきました。
実は、「closest()」が特定の親要素を検索して見つけた場合、戻り値として「length」を返してくれます。
この「length」の値が示す意味は以下のとおりです!
・「lengthが0」:指定の親要素を検索したが見つからなかった
・「lengthが1」:指定の親要素を検索して見つかった
この点を踏まえて、次のサンプル例を見てください!
<body> <div class="wrap"> <div class="content"> <p>サンプルテキスト</p> </div> </div> <script> var result1 = $('p').closest('.content').length; var result2 = $('p').closest('.main').length; console.log( 'content:' + result1 ); console.log( 'main:' + result2 ); </script> </body>
実行結果
content:1 main:0
この例では、2つのdivタグに囲まれたp要素が配置されています。
このp要素に対して「closest(‘.content’).length」と記述することで、class属性値「content」が付与された親要素のlengthを取得できます。
実行結果を見ると、「content」が付与された親要素は存在するので「1」となっているのが分かりますね。
逆に「main」が付与された親要素は存在しないので「0」が出力されています。
つまり、このlengthを活用することで特定の親要素が存在するかどうか?…を調べることができるわけです!
戻り値を活用した条件分岐処理の書き方
それでは、実際に「length」を活用した条件分岐を作ってみましょう!
JavaScriptでは、「0」という値は「false」と同じ意味になるので、これを上手く活用するとIF文に応用できますね。
次のサンプル例を見てください!
<body> <div class="wrap"> <div class="content"> <p>サンプルテキスト</p> </div> </div> <script> var result = $('p').closest('.main').length; if( result ) { console.log('存在します'); } else { console.log('存在しません!') } </script> </body>
実行結果
存在しません!
この例では、先ほどのHTMLを活用しています。
まず、p要素に対して「closest(‘.main’).length」と記述することで戻り値である「length」を取得しています。
そのうえで、取得した値を使って「IF文」を作っているのが分かりますね。
実際にはclass属性値「main」が付与された親要素は存在しません。
そのため、lengthの値は「0」となるのでfalseの処理が実行された結果「存在しません!」が出力されたというわけです。
このように、親要素の有無によって条件分岐させる処理をしたい場合には「closest()」が有効なので、ぜひ参考にしてみてください!
「closest」と「parent」の違い
jQueryには「closest()」とよく似たメソッドとして「parent()」メソッドがあります。
両者の最も大きな違いとしては以下の通りです!
・「parent()」は1つ上の階層にある親要素を取得する
・「closest()」は特定の親要素を見つけるまで階層を辿っていく
上記のポイントを抑えたうえで、次のサンプル例を見てください!
<body> <div class="wrap"> <div class="content"> <div> <p>サンプルテキスト</p> </div> </div> </div> <script> var result = $('p').parent('.content'); console.log( result ); </script> </body>
この例では、3つのdivタグに囲まれたp要素が配置されています。
このp要素に対して、class属性値「content」が付与された親要素を取得しようとしているのが分かりますね。
しかしながら、parent()は1つ上の階層にある親要素しか取得できません。
1つ上の階層にはclass属性値が無いdivタグしかないので、結果的に何も取得できないことになるわけです。
これと同じことを「closest()」を使ってやってみましょう!
var result = $('p').closest('.content'); console.log( result );
実行結果
[div.content, ......]
今度は、class属性値「content」が付与された親要素がある階層まで辿っていくので取得できますね。
このように階層の深さによって「parent / closest」の使い分けをしていくのが簡単な方法となります。
ちなみに、parent()の基本的な使い方や活用事例、parents()との違いなどの詳しい解説は次の記事が参考になるのでぜひチェックしてみてください!
「closest」と「find」の違い
「closest」のもう1つの類似メソッドとして「find」があるので合わせてご紹介しておきます!
「find」は、親要素ではなく「子要素」を検出するのに最適なメソッドになっています。
簡単に言うと「closest」の逆パターンとして使えるのでペアで覚えておくと良いでしょう。
・「find()」は特定の子要素を見つけるまで階層を辿っていく
・「closest()」は特定の親要素を見つけるまで階層を辿っていく
次のサンプル例を見て下さい!
<body> <div id="wrap"> <p>テキスト</p> <div> <a href="#">リンク</a> </div> </div> <script> var result1 = $('#wrap').find('a'); var result2 = $('#wrap').closest('a'); console.log( result1[0] ); console.log( result2[0] ); </script> </body>
実行結果
<a href="#">リンク</a> undefined
この例では、id属性値「wrap」が設定されたdivタグを対象にして子要素の「aタグ」を取得しようとしています。
「find」を使った場合は実行結果にしっかりと「aタグ」が取得できていることが分かりますね。
しかし、「closest」を使った場合は「undefined」となり、取得できていないことを意味しています。
理由は簡単で、「closest」はあくまでも親要素を取得するためのメソッドだからです。
ちなみに、「find」の基本から応用技までを次の記事でもまとめているのでぜひ参考にしてみてください!
まとめ
今回は、jQueryで特定の親要素を取得するのに便利な「closest()」メソッドの使い方を学習しました。
最後に、もう一度ポイントをおさらいしておきましょう!
・「closest()」を使えば特定の親要素を階層を辿って検索できる
・第2引数を指定することで検索範囲を指定できる
・「parent()」との違いは階層の深さ
・「戻り値」を使えば親要素の有無によって条件分岐できる
上記ポイントを踏まえて、ぜひ自分でも積極的にプログラミングに活用しながら勉強するように頑張りましょう!