DOMをトラバースする方法

提供:Dev Guides
移動先:案内検索

序章

このシリーズの前回のチュートリアルであるDOMの要素にアクセスする方法では、documentオブジェクトの組み込みメソッドを使用して、ID、クラス、タグ名でHTML要素にアクセスする方法について説明しました。 、およびクエリセレクタ。 DOMはノードのツリーとして構造化されており、ルートにdocumentノードがあり、さまざまなブランチとして他のすべてのノード(要素、コメント、テキストノードを含む)があります。

多くの場合、事前にすべての要素を指定せずにDOM内を移動する必要があります。 JavaScriptとHTMLの操作方法を理解するには、DOMツリーを上下に移動してブランチ間を移動する方法を学ぶことが不可欠です。

このチュートリアルでは、親、子、および兄弟のプロパティを使用してDOMをトラバースする方法(DOMのウォーキングまたはナビゲートとも呼ばれます)について説明します。

設定

まず、次のコードで構成されるnodes.htmlという新しいファイルを作成します。

ノード.html

<!DOCTYPE html>
<html>

<head>
  <title>Learning About Nodes</title>

  <style>
    * { border: 2px solid #dedede; padding: 15px; margin: 15px; }
    html { margin: 0; padding: 0; }
    body { max-width: 600px; font-family: sans-serif; color: #333; }
  </style>
</head>

<body>
  <h1>Shark World</h1>
  <p>The world's leading source on <strong>shark</strong> related information.</p>
  <h2>Types of Sharks</h2>
  <ul>
    <li>Hammerhead</li>
    <li>Tiger</li>
    <li>Great White</li>
  </ul>
</body>

<script>
  const h1 = document.getElementsByTagName('h1')[0];
  const p = document.getElementsByTagName('p')[0];
  const ul = document.getElementsByTagName('ul')[0];
</script>

</html>

ファイルをWebブラウザーにロードすると、次のスクリーンショットのようなレンダリングが表示されます。

このサンプルWebサイトには、いくつかの要素を含むHTMLドキュメントがあります。 styleタグにいくつかの基本的なCSSが追加され、各要素がはっきりと見えるようになりました。また、いくつかの要素に簡単にアクセスできるように、scriptにいくつかの変数が作成されました。 h1p、およびulはそれぞれ1つしかないため、それぞれのgetElementsByTagNameプロパティの最初のインデックスにアクセスできます。

ルートノード

documentオブジェクトは、DOM内のすべてのノードのルートです。 このオブジェクトは、実際にはwindowオブジェクトのプロパティです。これは、ブラウザのタブを表すグローバルな最上位オブジェクトです。 window オブジェクトは、ツールバー、ウィンドウの高さと幅、プロンプト、アラートなどの情報にアクセスできます。 documentは、内側のwindowの内側にあるもので構成されています。

以下は、すべてのドキュメントに含まれるルート要素で構成されるチャートです。 空白のHTMLファイルがブラウザーにロードされた場合でも、これらの3つのノードが追加されてDOMに解析されます。

財産 ノード ノードタイプ
document #document DOCUMENT_NODE
document.documentElement html ELEMENT_NODE
document.head head ELEMENT_NODE
document.body body ELEMENT_NODE

htmlhead、およびbody要素は非常に一般的であるため、documentに独自のプロパティがあります。

DevToolsでConsoleを開き、これら4つのプロパティを送信して出力を表示することにより、これらの各プロパティをテストします。 h1p、およびulをテストして、scriptタグに追加した変数による要素を返すこともできます。

親ノード

DOM内のノードは、他のノードとの関係に応じて、親、子、および兄弟と呼ばれます。 任意のノードのparentは、その1つ上のレベル、またはDOM階層のdocumentに近いノードです。 親を取得するには、parentNodeparentElementの2つのプロパティがあります。

財産 取得
parentNode 親ノード
parentElement 親要素ノード

nodes.htmlの例では、次のようになります。

  • htmlは、headbody、およびscriptの親です。
  • bodyは、h1h2pulの親ですが、[X89X]ではありません。 ] は、bodyから2レベル下にあります。

parentNodeプロパティを使用して、p要素の親が何であるかをテストできます。 このp変数は、カスタムdocument.getElementsByTagName('p')[0]宣言から取得されます。

p.parentNode;
Output► <body>...</body>

pの親はbodyですが、2レベル上の祖父母を取得するにはどうすればよいですか? これは、プロパティをチェーン化することで実現できます。

p.parentNode.parentNode;
Output► <html>...</html>

parentNodeを2回使用して、pの祖父母を取得しました。

以下のスニペットに示されているように、ノードの親を取得するためのプロパティがありますが、それらの間にはわずかな違いが1つだけあります。

// Assign html object to html variable
const html = document.documentElement;

console.log(html.parentNode); // > #document
console.log(html.parentElement); // > null

テキストとコメントを他のノードの親にすることはできないため、ほとんどすべてのノードの親は要素ノードです。 ただし、htmlの親はドキュメントノードであるため、parentElementnullを返します。 一般に、parentNodeは、DOMをトラバースするときによく使用されます。

子ノード

ノードのchildrenは、その1つ下のレベルにあるノードです。 ネストの1つのレベルを超えるノードは、通常、子孫と呼ばれます。

財産 取得
childNodes 子ノード
firstChild 最初の子ノード
lastChild 最後の子ノード
children 要素の子ノード
firstElementChild 最初の子要素ノード
lastElementChild 最後の子要素ノード

childNodesプロパティは、ノードのすべての子のライブリストを返します。 ul要素が3つのli要素を取得することを期待するかもしれません。 何を取得するかをテストしてみましょう。

ul.childNodes;
Output► (7) [text, li, text, li, text, li, text]

3つのli要素に加えて、4つのテキストノードも取得します。 これは、独自のHTML(JavaScriptによって生成されたものではない)を作成し、要素間のインデントがDOMでテキストノードとしてカウントされるためです。 DevToolsのElementsタブは空白ノードを取り除くため、これは直感的ではありません。

firstChildプロパティを使用して最初の子ノードの背景色を変更しようとすると、最初のノードがテキストであるため失敗します。

ul.firstChild.style.background = 'yellow';
OutputUncaught TypeError: Cannot set property 'background' of undefined

childrenfirstElementChild、およびlastElementChildプロパティは、要素ノードのみを取得するこれらのタイプの状況に存在します。 ul.childrenは、3つのli要素のみを返します。

firstElementChildを使用して、ulの最初のliの背景色を変更できます。

ul.firstElementChild.style.background = 'yellow';

上記のコードを実行すると、ウェブページが更新されて背景色が変更されます。

この例のような基本的なDOM操作を行う場合、要素固有のプロパティは非常に役立ちます。 JavaScriptで生成されたWebアプリでは、空白の改行とインデントが存在しないため、すべてのノードを選択するプロパティが使用される可能性が高くなります。

for ... of ループを使用して、すべてのchildren要素を反復処理できます。

for (let element of ul.children) {
  element.style.background = 'yellow';
}

これで、各子要素の背景が黄色になります。

p要素にはテキストと要素の両方が含まれているため、childNodesプロパティはその情報にアクセスするのに役立ちます。

for (let element of p.childNodes) {
  console.log(element);
}
Output"The world's leading source on "
<strong>​shark​</strong>​
" related information."

childNodeschildrenは、すべての配列プロパティとメソッドを含む配列を返しませんが、JavaScript配列と同様に表示および動作します。 インデックス番号でノードにアクセスするか、ノードのlengthプロパティを見つけることができます。

document.body.children[3].lastElementChild.style.background = 'fuchsia';

上記のコードは、bodyの4番目の子要素(ul)の最後の要素の子(li)を見つけて、スタイルを適用します。

親と子のプロパティを使用して、DOM内の任意のノードを取得できます。

兄弟ノード

ノードの兄弟は、DOM内の同じツリーレベルにある任意のノードです。 兄弟は同じタイプのノードである必要はありません。テキスト、要素、コメントノードはすべて兄弟にすることができます。

財産 取得
previousSibling 前の兄弟ノード
nextSibling 次の兄弟ノード
previousElementSibling 前の兄弟要素ノード
nextElementSibling 次の兄弟要素ノード

兄弟プロパティは、すべてのノードをトラバースするための一連のプロパティと、要素ノードのみの一連のプロパティがあるという点で、子ノードと同じように機能します。 previousSiblingおよびnextSiblingは、指定されたノードの直前または直後の次のノードを取得し、previousElementSiblingおよびnextElementSiblingは要素ノードのみを取得します。

nodes.htmlの例では、ulの中央の要素を選択しましょう。

const tiger = ul.children[1];

JavaScript Webアプリとしてではなく、ゼロからDOMを作成したため、DOMには空白があるため、要素の兄弟プロパティを使用して前の要素ノードと次の要素ノードにアクセスする必要があります。

tiger.nextElementSibling.style.background = 'coral';
tiger.previousElementSibling.style.background = 'aquamarine';

このコードを実行すると、coralHammerheadの背景に適用され、aquamarineGreat Whiteの背景に適用されているはずです。

親とノードのプロパティと同じように、兄弟のプロパティをチェーン化できます。

結論

このチュートリアルでは、すべてのHTMLドキュメントのルートノードにアクセスする方法と、親、子、および兄弟のプロパティを介してDOMツリーをウォークスルーする方法について説明しました。

DOMの要素にアクセスする方法とこのチュートリアルで学んだことにより、任意のWebサイトのDOMの任意のノードに自信を持ってアクセスできるはずです。