javascript DOM:WEBサイトデータをブラウザ上で変更できる機能

javascript DOM:WEBサイトデータをブラウザ上で変更できる機能

javascript DOM:WEBサイトデータをブラウザ上で変更できる機能

javascript DOMはブラウザ上のWEBデータ(Documentオブジェクト)に対して様々な変更を加える事ができるものです。

WEBページの階層構造や各ノードを軸にして特定個所を検索し、追加や変更・削除などを実行する事が可能です。

javascript DOMには様々なメソッドがあり、それを覚える事で様々な変化をさせる事ができます。

javascript DOMとは何か?

本記事はJavaScript初心者の方向けに、ブラウザにおけるJavaScript開発の基礎となるDOMについて解説します。

JavaScriptの一番の役目は、描画されたWEBページの表示を用途に応じて変化させる事です。

WEBページの記述をJavascriptによって変更するためには、DOMの知識が必須となります。

DOMを知る事がJavascriptコード書く際の指針になると言えるでしょう。

DOMとは

DOMとは「Document Object Model」の略で、先述した通りJavascriptでhtmlソースコードを操作するための仕組みです。

ブラウザに表示される文字の大きさや色等の表現は、前もってHTMLとCSSで構成されたものですよね。

設置されたHTMLとCSSで指定された内容通りに、WEBページが描画される訳です。

WEBページの表示を変えたい

ただし時には、描画内容を後から変更したい場合が出てきます。

例えば条件によって文字の色を変えたり大きくしたり、内容を追加したり消したり等、その用途は様々です。

これらは全てページを閲覧しているユーザーのためです。視覚的変化が全く起きないWEBページではユーザーを満足させる事はできません。

ユーザーの要望に応えるWEBページとなるために、WEBページ表示の変更機能は必須でしょう。

構成ファイルは変更できない

ところがサーバーにアップされているHTMLやCSSファイルは構成が固定されているため、変更を加える事はできません。

この時HTMLやCSSファイルを変更せず、出力されたブラウザ上のデータに直接変更を加えるのがDOMです。

データの変更対象箇所(Aの部分)を決めて(Bに変更する)変更処理を掛ける事ができます。

ブラウザがWEBページを表示する仕組み

まずはブラウザがWEBページを読み込む仕組みを簡単にご紹介しましょう。

DOMの生成イメージ

ブラウザはまず、WEBサーバーから受け取ったHTMLとCSSを解析してDOMと呼ばれるデータ構造に変換します。

このDOMデータが画面にレンダリングされる訳です。

生成データを変換・格納

つまりHTMLとCSSとで構成されたデータを、ブラウザの中にあるDOMというデータに変換・格納した状態です。

これは、HTML・CSSファイルとは別の位置にデータが生成・格納されている事になります。

Javascriptを使ってブラウザ内部にあるこのDOMにアクセスし、その内容を書き換えることができる訳です。

DOMが書き換えられると、新たなDOMに応じて瞬時に画面内容が再描画される仕組みで、ページ遷移の必要がなく描画自体が変わってくれるのが特徴です。

DOMデータのある場所

Windowオブジェクトの中にある

DOMデータは、Windowオブジェクトの中の一項目に存在します。

Windowオブジェクトとはブラウザが持っている情報丸ごとを指します。

Windowオブジェクトは、今開いているブラウザタブが持つあらゆる情報を格納しています。

Documentオブジェクト

このWindowオブジェクトの中には様々な項目プロパティがありますが、中でも重要なのが「documentプロパティ」です。

このdocumentプロパティの中に入っているのが、WEB生成データである「Documentオブジェクト」になります。

Documentオブジェクトは、構成されたHTMLのコンテンツ情報を全て保持する役割を持っています。

ブラウザ全体の情報…Windowオブジェクトが保有
WEBサイトに関する情報…Documentオブジェクトが保有

HTMLとCSSで生成されたWEBページのデータは、このDocumentオブジェクトの中に入っている訳ですね。

DOMは、このDocumentオブジェクト内にあるデータに対して要素の取得・操作などを実行します。

反映されたデータがブラウザに表示される事になります。

HTML上の道しるべ「階層構造」

ではDOMはどのようにして「Aの場所をBに変更する」という命令を実行するのでしょうか。

もちろんページを視覚的にみている訳ではありません。私たちユーザーとは見方が違うのです。

DOMはツリー構造で見ている

DOMは、HTMLによって出力された要素の関係を「ツリー構造」で見ています。

HTMLソースの階層構造

HTML文章を画面に表示すると、上記の様なツリー構造になっている事がわかります。

要素は必ず別の要素の内側か外側か同位置、いずれかに属する事になりますね。

この階層構造が、Javascriptによって変更を加える際の「道しるべ」になる訳です。

場所を特定するために、プログラム側としては階層構造を導線にする必要があるのです。

HTML側でも受ける準備

逆に言えばきちんとした階層構造でHTMLを構築しておく必要がありますね。

でないとJavascriptが目印をつける時に迷ってしまい、正常に稼働しない場合があります。

ですのでJavascriptで後から変更を加える事を前提として、HTML側で準備しておく必要があります。

各要素やタグを示す「ノード」

目印となる階層構造とともに重要なのが、要素の指定の仕方です。

上の図にあるように、HTML上の要素やタグ自体のことを「ノード」と呼びます。

ノードには様々な呼び方・分類の仕方があります。

親・子・兄弟ノード

ノードを、階層の位置関係によって家族名称をつけて呼ぶ事があります。

そのためには基準となるノードを指定します。基準が変われば親子関係も変わりますからね。

・親ノード
・子ノード
・兄弟ノード

指定されたノードに対し、その上位階層にあるノードを「親ノード」と呼び、その配下にあるノードを「子ノード」と呼びます。

また同一階層にあるノードのことを「兄弟ノード」と表現します。

基準ノードによる呼び方の違い

要素・テキストノード

家族間でノードを示す以外にも、大きく2つのノード分類ができます。

・要素ノード
・テキストノード

「要素ノード」はHTML要素自体を示し、それぞれに属性やstyle情報が付与されています。

「テキストノード」は要素や属性を持っていないテキスト部分を指します。

JavascriptでDOMのデータを書き換えるためには、ブラウザ上のDOMから特定のノード情報(目印)を取得しなければなりません。

先程も言いましたがWEBページの表面を見ている訳ではないので、階層構造とノードを頼りに場所を特定する必要があります。

DOMにより取得したノード情報を書き換える事で、ブラウザ上のWEBページ表示を変える事ができる訳です。

DOMは言われた事しかしませんから、希望する変更結果になるようにHTMLを整備する必要がありますね。

ノードの検索・取得

まずは変更する箇所を特定する事が先決です。そのためには階層構造上のノードを検索する必要があります。

対象を検索するメソッドには様々なものがあります。

・getElementById
・querySelector
・querySelectorAll

id名やclass名、あるいは親子関係などを使って、対象とする箇所を検索・特定していきます。

id属性の検索

getElementById

「getElementById」は、id属性を指定する最も有名な命令です。

<h1 id="check1"></h1>

上記のh1タグ内id=""の中に入った「check1」がid属性ですね。

getElementByIdは、DOM全体から指定されたid属性を持つ要素ノードを検索し、見つからなければnullを返します。

<script> const h1 = document.getElementById("check1"); console.log(h1); </script>

これで、check1というidを持った要素を丸ごと取得してきます。

Consoleに表示を切り替えると、h1タグで囲まれたすべてが取得されているのが確認できます。

セレクタによる検索

querySelector

「querySelector」は、セレクタ文字列を検索・指定します。

セレクタ文字列とは、HTML上のdivやh1-6、p、sectionなどの要素タグを示します。

「querySelector」は「getElementById」と同じように、単一の要素ノードを返します。

一致する要素がDOM中に複数ある場合は、HTML上一番上に書かれている要素が取得され、見つからない場合はnullを返します。

<script> const check = document.querySelector('#check1'); </script>

上記の場合、idがcheck1になっているセレクタ(HTMLタグ)を一つ指定する事になります。

querySelectorAll

「querySelectorAll」は、セレクタに合致する複数の要素を返します。

具体的には、NodeListオブジェクトが返され、見つからない場合は空のNodeListが返されます。

<script> const checks = document.querySelectorAll('.check'); </script>

上記の場合、クラス名にcheckがついているセレクタを全て探すことになります。

※返されるNodeListはノードが複数集まった集合体で、配列のようなイメージと考えて下さい。

特定ノード範囲からの検索

documentがHTML全体から要素を検索するのに対し、特定の要素範囲から指定のセレクタを検索することもできます。

<div class="box"> <p class="btn">クリックして下さい</p> </div>
<script> const box = document.querySelector('.box'); const btn = box.querySelector('.btn'); </script>

上記の場合、boxクラス名を付与された要素内からbuttonクラスのついたノードを返します。

親要素からの取得

さらに階層構造を活かした検索も可能です。

例えばある要素の親要素の場合、parentNodeプロパティからアクセスできます。

<div class="box"> <p class="btn">クリックして下さい</p> </div>
<script> const btn = document.querySelector('.btn'); const box = btn.parentNode; </script>

上記の場合、buttonセレクタの親要素ノード「div」を取得しています。

子要素からの取得

childNodesやchildrenプロパティを使えば、子要素を取得できます。

childNodes

<ul> <li>Red</li> <li>Blue</li> <li>Green</li> </ul>
<script> const list = document.querySelector('ul'); const listItems = list.childNodes; </script>

childNodesプロパティは、子要素の一覧を表すNodeListにのみアクセスでき、孫やそれ以降のノードは含まれません。

RedやBlueのテキスト部分(テキストノード)も含んで丸ごと対象になります。

children

同様の効果を持つchildrenプロパティは、HTML要素のみの一覧を返すためテキストノードは含みません。

<script> const listItems = list.children; </script>

兄弟要素からの取得

ある要素の兄弟、つまり隣り合った要素を取得する方法もあります。

nextSibling

nextSiblingプロパティは、同列にあるノードを返します。

<p id="item1">Red</p> <p id="item2">Blue</p> <p id="item3">Green</p>
<script> const one = document.querySelector('#item1'); console.log(one.nextSibling); </script> 空白のノードが返る

上記の場合、2つ目の<p id="item2">blue</p>の部分が返るはずですが、実はそうはならず空白のテキストノードが返されます。

これはなぜかというと、コード上の改行やホワイトスペースも、テキストノードの形でDOMの一部に組み込まれるためです。

つまり「改行部分」が、2つ目としてカウントされていることになりますね。

nextElementSibling

ここで「nextElementSibling」プロパティを使えば、改行やスペースなどのテキストノードを除いた次の要素を返します。

<script> const one = document.querySelector('#item1'); console.log(one.nextElementSibling); </script> <p id="item2">Blue</p>が取得される

属性の取得と更新

属性値の操作

要素の属性値は、getAttributeやsetAttributeメソッドで取得したり更新したりします。

DOMにおいては、付与された属性を取得して操作する事が基本になります。

属性値の取得

<script> const content = element.getAttribute('content'); </script>

属性値の更新

<script> element.setAttribute('title', 'content'); 属性値titleがcontentに代わる </script>

クラス属性の操作

クラス属性は値を複数持つため、classListプロパティを使って操作します。

クラスを追加する

<script> element.classList.add('check1'); class=""にcheck1が追加される </script>

クラスを削除する

<script> element.classList.remove('check1'); </script>

クラスの有無を切り替える

<script> element.classList.toggle('check1'); 実行されるたびつけ外しがされる </script>

クラス属性のあり・なし確認

<script> element.classList.contains('check1'); あればtrue、なければfalse </script>

カスタムデータ属性

開発者がHTML要素にオリジナルの属性を設定する場合は、data-で始まる命名を用いるのが標準仕様です。

<div id="item" data-my-name="Red">...</div>

これらの属性はカスタムデータ属性と呼ばれます。

Javascriptの場合、datasetプロパティから以下のように値にアクセスできます。

<script> const element = document.querySelector('#item'); console.log(element.dataset.myName); ここが現在は「Red」 element.dataset.myName = 'Brue'; 「Blue」に変更 </script>

カスタムデータ属性は、Javascriptとの連携が主な目的となります。

ある要素に、その要素特有のデータを持たせる事ができ、idやclassとは違います。

idは文書の中である要素を1つ特定するための属性であり、classは要素を複数特定してグループ化する属性です。

これに対してカスタムデータ属性は、要素にアプリケーション固有の設定値を与えることができます。

変更を前提とするデータについては前もってカスタムデータとしておき、JavascriptでDOM変更を加えるのが主流になります。

DOMの生成・追加

新しいDOMを生み出す

Javascriptを使えば、最初のDOM上に存在していない要素を生み出す事もできます。

<p>テキスト1</p> <p>テキスト2</p>

pタグの「テキスト1・2」ありますが、ここにもう1つpタグを作成して追加してみましょう。

要素を生成するには、createElementメソッドを用います。

要素内のテキストを生成するには、createTextNodeメソッドを用います。

<script> const p = document.createElement('p'); const text = document.createTextNode("テキスト3"); </script>

しかしこのままではまだ「テキスト3」の入ったpタグが、どの親要素の下につくかを指定していません。

ですので実行してもまだ追加はされないのですね。

DOMを新しく追加する

ですので「要素3」をブラウザで表示させるためには、既存の要素のどれかを親要素に指定し、子要素として追加する必要があります。

appendChild

特定の親要素の下に子要素を追加するためのメソッドが、appendChildメソッドです。

bodyタグを親として指定し、作ったp要素を子要素として追加してみます。

<p>要素1</p> <p>要素2</p>
<script> const p = document.createElement('p'); const text = document.createTextNode("テキスト3"); document.body.appendChild(p).appendChild(text); </script>

挿入後

<p>要素1</p> <p>要素2</p> <p>要素3</p>

その他の追加メソッド

また他にも、要素を挿入する方法はたくさんあります。

innerHTMLプロパティ
insertAdjacentElementメソッド
insertBeforeメソッド

DOMを削除する

removeメソッドを用いれば、既存のDOM上の要素を削除する事もできます。

removeメソッド

<script> element.remove(); </script>

ただしIEでは動作しないため、ポリフィルを読み込むか以下の方法で実現しましょう。

一度親要素を取得してから removeChild を実行する

<script> const parent = element.parentNode; parent.removeChild(element); </script>

以上本記事では、JavaScriptの超基礎講座として、DOMの操作方法を見ていきました。

DOMとは何か、そして要素の検索・取得・作成・追加・削除という基本操作を紹介しました。

本記事は単なるさわりの部分でしかなく、他にDOMメソッドはたくさん用意されています。色々調べて見て下さい。

この記事をシェアする

一押し人気コーナー紹介

HTMLカテゴリの関連記事