序章
このシリーズの前回のチュートリアルである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の任意のノードに自信を持ってアクセスできるはずです。