JavaScriptのclosestを利用して最も近い祖先要素を操作する7つの方法

JavaScriptのclosestメソッドを使った最も近い祖先要素の操作方法 JS
この記事は約17分で読めます。

【サイト内のコードはご自由に個人利用・商用利用いただけます】

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

基本的な知識があればサンプルコードを活用して機能追加、目的を達成できるように作ってあります。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を凌駕する現役のプログラマチームによって監修されています。

サイト内のコードを共有する場合は、参照元として引用して下さいますと幸いです

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

●JavaScriptのclosestメソッドとは?

JavaScriptを使ってWebサイトやアプリケーションを開発していると、特定の条件を満たす祖先要素を取得したいというシーンに遭遇することがよくあります。

そんな時に活躍するのがclosestメソッドです。

closestメソッドは、指定した要素から見て、最も近い祖先要素を効率的に探し出してくれる頼もしい味方なのです。

○closestメソッドの基本的な使い方

closestメソッドの使い方は至ってシンプルです。

まず、closestメソッドを適用したい要素を選択します。

そして、closestメソッドに引数としてセレクタを渡すだけ。

するとclosestメソッドは、指定したセレクタに合致する最も近い祖先要素を見つけ出し、その要素を返してくれます。

まるで迷子になった子供を優しく家まで送り届けてくれるかのようですね。

○サンプルコード1:最も近い祖先要素を取得する

実際のコードを見てみましょう。

次のようなHTMLがあるとします。

<div class="grandparent">
  <div class="parent">
    <div class="child">孫要素</div>
  </div>
</div>

ここで、孫要素から見て最も近い”parent”クラスを持つ祖先要素を取得したいとします。

その場合、このようなJavaScriptコードを書けば、目的の要素を手に入れることができます。

const child = document.querySelector('.child');
const parent = child.closest('.parent');
console.log(parent); // <div class="parent">...</div>

childという変数に孫要素を代入し、その要素に対してclosestメソッドを使って’.parent’セレクタを渡しています。

するとclosestメソッドは、孫要素から見て最も近い”parent”クラスを持つ要素を見つけ出し、その要素をparent変数に代入してくれます。

これでめでたく目的の祖先要素を取得できました。

○closestメソッドのブラウザ対応状況

ところで、closestメソッドって新しめのメソッドなのでは?と思った方もいるかもしれません。

実はその通りで、closestメソッドが登場したのはそれほど昔のことではありません。

しかし、現在ではほとんどのモダンブラウザでclosestメソッドがサポートされています。

IEを含む古いブラウザでは使えないこともありますが、最新のChrome、Firefox、Safariなどでは問題なく動作します。

ただ、念のためにブラウザ対応状況を確認しておくことをおすすめします。

●closestメソッドを使った要素の取得方法

前章ではclosestメソッドの基本的な使い方を見てきましたが、実際の開発現場ではもっと複雑な条件で祖先要素を取得したいことがあります。

そんな時にもclosestメソッドは力を発揮してくれます。

ここからは、closestメソッドをさらに使いこなすためのテクニックを見ていきましょう。

○サンプルコード2:特定のクラスを持つ祖先要素を取得する

まずは、特定のクラスを持つ祖先要素を取得する方法です。

次のようなHTMLがあるとします。

htmlCopy code<div class="grandparent">
<div class="parent">
<div class="child">孫要素</div>
</div>
</div>

ここで、孫要素から見て最も近い”grandparent”クラスを持つ祖先要素を取得したいとします。

その場合、以下のようなコードを書けば目的を達成できます。

javascriptCopy codeconst child = document.querySelector('.child');
const grandparent = child.closest('.grandparent');
console.log(grandparent); // <div class="grandparent">...</div>

childから見て、”grandparent”クラスを持つ最も近い祖先要素を取得しています。

たとえ途中に他の要素があっても、目的の要素をしっかりと見つけ出してくれます。

○サンプルコード3:複数の条件を満たす祖先要素を取得する

次に、複数の条件を満たす祖先要素を取得する方法を見てみましょう。

次のようなHTMLを考えます。

htmlCopy code<div id="ancestor" class="grandparent">
<div class="parent">
<div class="child">孫要素</div>
</div>
</div>

今度は、”grandparent”クラスを持ち、かつ”ancestor”というIDを持つ祖先要素を取得したいとします。

そんな時は、このようにコードを書けば大丈夫です。

javascriptCopy codeconst child = document.querySelector('.child');
const ancestor = child.closest('.grandparent#ancestor');
console.log(ancestor); // <div id="ancestor" class="grandparent">...</div>

セレクタの中で、クラスとIDを組み合わせることで、より詳細な条件で祖先要素を特定することができます。

まるで迷路の中でゴールを目指すかのように、closestメソッドが目的の要素へと導いてくれます。

○サンプルコード4:closestメソッドとquerySelectorの組み合わせ

ここからは、closestメソッドとquerySelectorメソッドを組み合わせるテクニックを紹介します。

次のようなHTMLを想定してください。

htmlCopy code<div class="grandparent">
<div class="parent">
<div class="child">
<span>孫要素</span>
</div>
</div>
</div>

今回は、孫要素の中にあるspan要素から、”parent”クラスを持つ祖先要素を取得したいとします。

その場合、以下のようなコードを書くことができます。

javascriptCopy codeconst span = document.querySelector('.child span');
const parent = span.closest('.parent');
console.log(parent); // <div class="parent">...</div>

まず、querySelectorメソッドを使ってspan要素を取得します。

そのspan要素に対してclosestメソッドを適用することで、目的の祖先要素を見つけ出すことができます。

closestメソッドとquerySelectorメソッドの組み合わせは、DOMの階層構造をたどる際に非常に便利です。

○サンプルコード5:jQueryのclosestメソッドとの比較

最後に、jQueryのclosestメソッドとの比較を見てみましょう。

jQueryを使っている方は、こんなコードを書いたことがあるかもしれません。

javascriptCopy codeconst child = $('.child');
const parent = child.closest('.parent');
console.log(parent); // jQueryオブジェクト

jQueryのclosestメソッドも、基本的な使い方はJavaScriptのclosestメソッドと同じです。

ただし、jQueryのclosestメソッドが返すのはjQueryオブジェクトであるのに対し、JavaScriptのclosestメソッドが返すのはDOM要素そのものです。

この違いを理解しておくことで、適切なメソッドを選択することができます。

自分が求める要素を的確に取得できるようになると、DOMを操作する際の自由度が格段に上がります。

closestメソッドを使いこなすことで、JavaScriptでのDOM操作がより快適になることでしょう。

●よくあるエラーと対処法

さて、ここまでclosestメソッドの使い方について詳しく見てきましたが、実際に使ってみると思わぬエラーに遭遇することがあります。

特に、JavaScriptを学び始めたばかりの頃は、エラーメッセージに戸惑ってしまうこともあるでしょう。

ここでは、closestメソッドを使う際によく遭遇するエラーとその対処法を見ていきましょう。

○エラー1:closestメソッドが期待通りに動作しない場合

まずは、closestメソッドが期待通りに動作しない場合のエラーです。

次のようなコードを書いたとします。

const element = document.querySelector('.child');
const ancestor = element.closest('div');
console.log(ancestor);

このコードは、”child”クラスを持つ要素から見て、最も近いdiv要素を取得しようとしています。

しかし、実際に実行してみると、nullが返ってきてしまうことがあります。

これはなぜでしょうか?

実は、このエラーの原因は、指定したセレクタに該当する祖先要素が存在しないことにあります。

つまり、”child”クラスを持つ要素から見て、div要素が祖先に存在しない場合、closestメソッドはnullを返すのです。

この場合の対処法は、セレクタを見直すことです。

HTMLの構造を確認し、目的の要素に到達できるセレクタを指定するようにしましょう。

また、nullチェックを行うことで、エラーを回避することもできます。

const element = document.querySelector('.child');
const ancestor = element.closest('div');
if (ancestor) {
  console.log(ancestor);
} else {
  console.log('div要素が見つかりませんでした');
}

○エラー2:closestメソッドが見つからない場合

次に、closestメソッドが見つからない場合のエラーを見てみましょう。

次のようなコードを書いたとします。

const element = document.querySelector('.child');
const ancestor = element.closet('.parent');
console.log(ancestor);

このコードでは、closestメソッドのスペルを間違えています(closetと書いている)。

そのため、実行するとエラーが発生します。

このエラーの対処法は単純で、スペルミスを修正することです。

正しくは、closestメソッドですね。

const element = document.querySelector('.child');
const ancestor = element.closest('.parent');
console.log(ancestor);

ちょっとしたタイプミスが原因でエラーが発生することは珍しくありません。

エラーメッセージをよく読んで、スペルミスがないか確認する習慣をつけましょう。

○エラー3:closestメソッドがnullを返す場合

最後に、closestメソッドがnullを返す場合のエラーを見てみましょう。

次のようなコードを考えます。

<div class="parent">
  <div class="child"></div>
</div>
const element = document.querySelector('.child');
const ancestor = element.closest('.grandparent');
console.log(ancestor.textContent);

このコードは、”child”クラスを持つ要素から、”grandparent”クラスを持つ祖先要素を取得しようとしています。

しかし、該当する要素が存在しないため、closestメソッドはnullを返します。

そして、nullに対してtextContentプロパティにアクセスしようとするため、エラーが発生するのです。

この場合の対処法は、nullチェックを行うことです。

次のように、closestメソッドの戻り値がnullでないことを確認してから、プロパティにアクセスするようにしましょう。

const element = document.querySelector('.child');
const ancestor = element.closest('.grandparent');
if (ancestor) {
  console.log(ancestor.textContent);
} else {
  console.log('grandparentクラスを持つ要素が見つかりませんでした');
}

エラーは悪者ではありません。むしろ、私たちにコードの問題点を教えてくれる良き友人だと思います。

エラーと向き合い、原因を探ることで、JavaScriptの理解がより深まっていくでしょう。

●closestメソッドの応用例

ここまでclosestメソッドの基本的な使い方やエラー処理について見てきましたが、実際の開発現場では、もっと応用的な使い方が求められることがあります。

ここからは、closestメソッドをさらに活用するためのテクニックを見ていきましょう。

私たちの開発スキルをレベルアップするチャンスです!

○サンプルコード6:イベントデリゲーションでclosestメソッドを活用する

まずは、イベントデリゲーションでclosestメソッドを活用する方法を見てみましょう。

イベントデリゲーションとは、親要素にイベントリスナーを設定し、子要素で発生したイベントを親要素で受け取る手法のことです。

<ul id="list">
  <li><a href="#">リンク1</a></li>
  <li><a href="#">リンク2</a></li>
  <li><a href="#">リンク3</a></li>
</ul>

ここで、各リンクをクリックした時に、そのリンクが属するli要素に特定の処理を行いたいとします。

その場合、以下のようなコードを書くことができます。

const list = document.getElementById('list');
list.addEventListener('click', function(event) {
  const target = event.target;
  const listItem = target.closest('li');
  if (listItem) {
    console.log(listItem.textContent);
  }
});

リスト全体に対してクリックイベントのリスナーを設定しています。

クリックされた要素(target)に対して、closestメソッドを使ってli要素を取得しています。

これにより、クリックされた要素が直接li要素でなくても、最も近いli要素を取得することができます。

イベントデリゲーションとclosestメソッドの組み合わせは、効率的なイベント処理を実現するための強力な手法です。

○サンプルコード7:動的に生成された要素にclosestメソッドを適用する

次に、動的に生成された要素にclosestメソッドを適用する方法を見てみましょう。

JavaScriptを使ってDOMを操作していると、動的に要素を追加することがよくあります。

そんな時も、closestメソッドは活躍してくれます。

<div id="container">
  <div class="child">子要素1</div>
  <div class="child">子要素2</div>
</div>
const container = document.getElementById('container');
const newChild = document.createElement('div');
newChild.textContent = '子要素3';
newChild.classList.add('child');
container.appendChild(newChild);

const child = newChild.closest('.child');
console.log(child.textContent); // '子要素3'

動的に新しいdiv要素を生成し、それをcontainer要素の子要素として追加しています。

追加された子要素に対して、closestメソッドを使って’.child’セレクターに一致する要素を取得しています。

このように、動的に生成された要素に対しても、closestメソッドを使うことができます。

○closestメソッドを使ったカスタムデータ属性の取得

続いて、closestメソッドを使ってカスタムデータ属性を取得する方法を見てみましょう。

カスタムデータ属性とは、data-で始まる属性のことで、要素に独自のデータを付与するために使われます。

<div id="container" data-id="123">
  <div class="child">
    <button>クリック</button>
  </div>
</div>
const container = document.getElementById('container');
container.addEventListener('click', function(event) {
  const target = event.target;
  const parent = target.closest('[data-id]');
  if (parent) {
    console.log(parent.dataset.id); // '123'
  }
});

container要素にdata-id属性を設定し、その値を’123’としています。

container要素内のボタンをクリックした時、closestメソッドを使ってdata-id属性を持つ要素を取得しています。

取得した要素のdatasetプロパティを使うことで、カスタムデータ属性の値を取得することができます。

○closestメソッドとarrowファンクションの組み合わせ

最後に、closestメソッドとarrowファンクションを組み合わせる方法を見てみましょう。

arrowファンクションは、関数を簡潔に記述するための構文で、thisの値を固定できるという特徴があります。

const child = document.querySelector('.child');
child.addEventListener('click', function(event) {
  const parent = this.closest('.parent');
  console.log(parent);
});

このコードでは、child要素をクリックした時、イベントハンドラー内でthisを使ってclosestメソッドを呼び出しています。

ここで、arrowファンクションを使うとこのように書くことができます。

const child = document.querySelector('.child');
child.addEventListener('click', (event) => {
  const parent = event.target.closest('.parent');
  console.log(parent);
});

arrowファンクションを使うことで、thisを使わずにevent.targetを使ってclosestメソッドを呼び出すことができます。

コードがよりシンプルになり、可読性が向上します。

まとめ

JavaScriptのclosestメソッドは、DOM操作において非常に便利なツールです。

closestメソッドを使うことで、指定した要素から見て最も近い祖先要素を効率的に取得することができます。

基本的な使い方から、特定の条件を満たす要素の取得、動的に生成された要素への適用など、様々な場面で活躍してくれるでしょう。

時にはエラーに遭遇することもありますが、エラーメッセージをよく読み、適切な対処を行うことが大切です。

本記事では、closestメソッドの基本から応用まで、実践的なサンプルコードを交えながら詳しく解説してきました。

これからは、皆さんがclosestメソッドを使いこなす番です。コードを書く際には、closestメソッドを積極的に活用してみてください。

最初は戸惑うこともあるかもしれませんが、使えば使うほどその便利さを実感できるはずです。

closestメソッドを味方につけることで、JavaScriptでのDOM操作がより快適になること間違いなしです。

今日学んだことを活かして、より洗練されたコードを書いていきましょう。

皆さんの開発者としてのさらなる成長を心から応援しています。