Prompt
JavaScriptで、
querySelector()などで要素を選択した後に、
その要素の親要素や、以前のテキスト、以後のテキスト要素などを取得する方法はある?
よしきた! JavaScriptでDOM操作するなら、要素の親子関係や兄弟関係をたどるのは必須スキルだよね! 質問ありがとう!
querySelector()などで要素を選択した後に、その要素から親要素や兄弟要素(前後のテキストノード含む) を取得する方法は、もちろんあるよ! 一緒に見ていこう!
1. 親要素を取得する
選択した要素から親要素を取得するには、いくつかのプロパティがあるよ。
-
parentNode:-
最も汎用的な親ノードの取得方法。 親が要素(
Element)だけでなく、テキストノードやコメントノード、DocumentFragmentなども含む、すべてのノードタイプを返す可能性があるよ。 -
通常、HTML要素の親は別のHTML要素だけど、例えばテキストノードの親を取得したい場合などにも使える汎用性があるんだ。
JavaScript
const childElement = document.querySelector('#child'); const parent = childElement.parentNode; console.log(parent); // <div id="parent">...</div> -
-
parentElement:-
親が
Element型(つまりHTML要素)の場合にのみ親要素を返す。親がテキストノードなど要素以外のノードだった場合はnullを返すよ。 -
ほとんどのケースでHTML要素の親要素が欲しい場面が多いから、
parentNodeよりこちらを使うことが多いかも。
JavaScript
const childElement = document.querySelector('#child'); const parent = childElement.parentElement; console.log(parent); // <div id="parent">...</div>(
html要素の親はnullになるよ) -
-
closest(selector):-
指定したセレクタに合致する最も近い祖先要素(自身も含む)を返すよ。
-
特定のクラスやIDを持つ親要素を探したい場合に便利!
HTML
<div id="grandparent"> <div class="container"> <div id="parent"> <p id="child">子要素</p> </div> </div> </div>JavaScript
const childElement = document.querySelector('#child'); const closestContainer = childElement.closest('.container'); console.log(closestContainer); // <div class="container">...</div> const closestGrandparent = childElement.closest('#grandparent'); console.log(closestGrandparent); // <div id="grandparent">...</div> -
2. 兄弟要素(前後の要素、テキストノード含む)を取得する
これは少し複雑だけど、いくつかのプロパティとメソッドがあるよ。
テキストノードも含む「すべてのノード」をたどる場合
要素だけでなく、空白文字や改行などのテキストノードも「ノード」として取得したい場合に使うよ。
-
previousSibling: 直前の兄弟ノードを返す。 -
nextSibling: 直後の兄弟ノードを返す。 -
firstChild: 最初の子ノードを返す。 -
lastChild: 最後の子ノードを返す。 -
childNodes: すべての子ノード(NodeList形式)を返す。
例:
HTML
<div id="container">
テキスト1
<p id="target">ターゲット</p>
テキスト2
<span>スパン</span>
</div>
JavaScript
const targetElement = document.querySelector('#target');
// 直前の兄弟ノード (ここでは「テキスト1」のテキストノード)
const prevNode = targetElement.previousSibling;
console.log(prevNode); // Textノード ("\n テキスト1\n ") - HTMLの改行やスペースもノードになる
// 直後の兄弟ノード (ここでは「テキスト2」のテキストノード)
const nextNode = targetElement.nextSibling;
console.log(nextNode); // Textノード ("\n テキスト2\n ")
要素ノードだけをたどる場合
余計なテキストノード(特にHTMLの整形による空白や改行)を除外して、純粋なHTML要素だけを対象にしたい場合によく使うよ。
-
previousElementSibling: 直前の兄弟要素を返す。 -
nextElementSibling: 直後の兄弟要素を返す。 -
firstElementChild: 最初の子要素を返す。 -
lastElementChild: 最後の子要素を返す。 -
children: すべての子要素(HTMLCollection形式)を返す。
例:
HTML
<div id="container">
<p>最初の要素</p>
<span id="targetElement">ターゲット</span>
<div>最後の要素</div>
</div>
JavaScript
const targetElement = document.querySelector('#targetElement');
// 直前の兄弟要素 (ここでは <p>要素)
const prevElem = targetElement.previousElementSibling;
console.log(prevElem); // <p>最初の要素</p>
// 直後の兄弟要素 (ここでは <div>要素)
const nextElem = targetElement.nextElementSibling;
console.log(nextElem); // <div>最後の要素</div>
3. 「以前のテキスト」「以後のテキスト」要素について
ここで言う「テキスト要素」が、純粋にTextノードを指すのか、それともテキストコンテンツを持つElementを指すのかで変わってくるけど、上記の「すべてのノードをたどる場合」のプロパティ(previousSiblingやnextSibling)を使えば、対象の要素の直前・直後のテキストノードを取得できるよ。
もし、そのテキストノードの中身が欲しい場合は、取得したノードのnodeValueプロパティを使えばいいんだ。
JavaScript
const targetElement = document.querySelector('#target'); // 上の例のHTMLを使う
const prevNode = targetElement.previousSibling;
if (prevNode && prevNode.nodeType === Node.TEXT_NODE) { // テキストノードか確認
console.log('直前のテキスト:', prevNode.nodeValue.trim()); // trim()で余計な空白を削除
}
const nextNode = targetElement.nextSibling;
if (nextNode && nextNode.nodeType === Node.TEXT_NODE) {
console.log('直後のテキスト:', nextNode.nodeValue.trim());
}
INFPの君は、自己表現やアウトプットを大切にすると言ってたよね。DOM操作をマスターすれば、JavaScriptを使ってWebページをよりダイナミックに、より表現豊かに操作できるようになるから、君のクリエイティブなアイデアを形にするのに役立つはずだよ! ぜひ色々と試してみてね!