DOMをトラバースする方法
序章
このシリーズの前回のチュートリアルである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
にいくつかの変数が作成されました。 h1
、p
、および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
|
html
、head
、およびbody
要素は非常に一般的であるため、document
に独自のプロパティがあります。
DevToolsでConsoleを開き、これら4つのプロパティを送信して出力を表示することにより、これらの各プロパティをテストします。 h1
、p
、およびul
をテストして、script
タグに追加した変数による要素を返すこともできます。
親ノード
DOM内のノードは、他のノードとの関係に応じて、親、子、および兄弟と呼ばれます。 任意のノードのparentは、その1つ上のレベル、またはDOM階層のdocument
に近いノードです。 親を取得するには、parentNode
とparentElement
の2つのプロパティがあります。
財産 | 取得 |
---|---|
parentNode
|
親ノード |
parentElement
|
親要素ノード |
nodes.html
の例では、次のようになります。
html
は、head
、body
、およびscript
の親です。body
は、h1
、h2
、p
、ul
の親ですが、[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
の親はドキュメントノードであるため、parentElement
はnull
を返します。 一般に、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
children
、firstElementChild
、および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."
childNodes
とchildren
は、すべての配列プロパティとメソッドを含む配列を返しませんが、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';
このコードを実行すると、coral
がHammerhead
の背景に適用され、aquamarine
がGreat White
の背景に適用されているはずです。
親とノードのプロパティと同じように、兄弟のプロパティをチェーン化できます。
結論
このチュートリアルでは、すべてのHTMLドキュメントのルートノードにアクセスする方法と、親、子、および兄弟のプロパティを介してDOMツリーをウォークスルーする方法について説明しました。
DOMの要素にアクセスする方法とこのチュートリアルで学んだことにより、任意のWebサイトのDOMの任意のノードに自信を持ってアクセスできるはずです。