JavaScriptからのDOM操作【初心者向けに基本から解説】

2018年12月18日火曜日

プログラミング

JavaScriptからのDOM操作

本日はJavaScript初心者の方に向けて、DOM操作というものについて解説をしていきたいと思います。

JavaScriptによるDOM操作とはどういうことかと言うと、
「JavaScriptによって、HTMLの内容を変更する」
ということですね。

これができるようになると、JavaScriptによってできることがグンと広がります。

この部分をマスターすれば、面白いアニメーションや、ゲームのようなものも作れるようになりますよ。

それでは、いってみましょう。

DOMとは?


JavaScriptのDOM操作について悩む女性

DOMとは「Document Object Model」の略で、分かりやすく言うと、JavaScriptからHTMLを操作する仕組みのことだと考えて良いでしょう。

ここで出てくるキーワードは、「document」です。

Webサイトを表現するためのHTML全体を、JavaScript上ではdocumentと呼んで扱っているのです。


JavaScriptによるDOMの取得


JavaScriptでのDOMの取り方を教える女性

口で説明するよりも、実際の動作を見た方が分かりやすいと思いますので、JavaScriptによるDOM取得の動きを確認してみましょう。

JavaScriptからHTMLの内容を変更・操作するためには、まずはその変更対象のHTML要素を、JavaScript側で読み込む必要があります。

ここではその読み込み方法として、以下の代表的な3つの関数をご紹介します。

  • getElementById(id);
  • getElementsByName(name);
  • getElementsByClassName(className);

getElementById(id);

読み:ゲット エレメント バイ アイディー

これは、HTML要素のid属性を利用して、JavaScript側でHTMLの要素を取得する方法です。

以下の例を見てもらった方が分かりやすいかもしれませんね。

試しに以下のボタンを押してみてください。



ボタンを押した際に、JavaScript側から、そのボタンの横幅が表示されますね。

これは、以下のようなソースコードで実現されています。

<!--HTML上に配置されたボタン-->
<button id="testButton1" onclick="fncBtn1();" style="width:150px;">
ボタン情報取得
</button>


<!--ボタンクリック時に動くJavaScript関数-->
<script>
  function fncBtn1(){

    // "testButton1"というidを指定して、
    // JavaScript側でHTML要素を取得
    var btn = document.getElementById("testButton1");

    //ボタンの幅を表示
    alert("ボタンの幅:" + btn.style.width);

  }
</script>

上記の例ではまず、HTML上にボタンを配置して、横幅を150pxと設定しています。

JavaScript側ではそのボタン要素を読み込んで、alert関数を使って、そのボタンの横幅を通知していますね。

ここで覚えて頂きたいのが、
document.getElementById
という記載です。

DOM(Document Object Model)という言葉にも、「document」という単語が含まれているように、JavaScriptからDOMの操作を行う際は、documentという記載を用います。

documentとはHTML全体のことを表していますから、getElementIdによって、documentの中の特定のidを持つ要素だけJavaScript側に抽出してきているのですね。


getElementsByName(name);

読み:ゲット エレメンツ バイ ネーム

上記のgetElementByIdと似たような関数に、getElementsByNameというものがあります。

こちらは少し注意点があるのですが、まずは使用例を見てみましょう。



先ほどの例と同様に、ボタンを押した際に、JavaScriptからボタンの横幅が通知されますね。

これは、以下のようなソースコードで実現されています。

<!--HTML上に配置されたボタン-->
<button name="testButton2" onclick="fncBtn2();" style="width:150px;">
ボタン情報取得
</button>


<!--ボタンクリック時に動くJavaScript関数-->
<script>
  function fncBtn2(){

    // "testButton2"というnameを指定して、
    // JavaScript側でHTML要素を取得
    var btn = document.getElementsByName("testButton2")[0];

    //ボタンの幅を表示
    alert("ボタンの幅:" + btn.style.width);

  }
</script>

idを指定する場合と、ほとんど同じように利用ができていますね。

しかし、少し違う部分があることに気が付きましたでしょうか?

比べてみると分かりやすいと思います。

idを指定する場合:
document.getElementById("testButton1");

nameを指定する場合:
document.getElementsByName("testButton2")[0];

違いは、[0]という記載ですね。
これは一体何なのでしょうか?

また、よく見ると、nameで指定する方は、「Element」ではなく「Elements」という風に、「s」がついていますね。

察しが良い方はお気づきかもしれませんが、これは、idがHTML全体で一意に要素を特定できるものなのに対して、nameは、同一のnameを持った要素が複数あるかもしれないことに起因しています。

要は、指定されたnameと同じ名前のものを全て、まとめて配列で取得しているのです。

配列の要素を取り出すためには、[0][1]のように、配列の中にある要素の番号を指定する必要がありますから、[0]という記載を付け加えて、配列の最初の要素を取得しているのですね。


getElementsByClassName(className);

読み:ゲット エレメンツ バイ クラス ネーム

上記のgetElementsByNameと、ほとんど同じような動きをする関数に、getElementsByClassNameというものがあります。

これは、HTML要素のclass属性の値を指定して、JavaScript側で読み込む関数です。

こちらもgetElementsByNameと同様に、複数の要素が配列に格納されて取得されます。

ですから、使い方はgetElementsByNameと全く一緒と考えて頂いても差し支えないでしょう。

今回の例では以下のように、3つのボタンを配置する例を見てみましょう。





先ほどの例と同様に、ボタンを押した際に、JavaScriptからボタンの横幅が通知されますね。
ただ、今回は3つのボタンに対して、それぞれ通知が行われます。

これは、以下のようなソースコードで実現されています。

<!--HTML上に配置されたボタン-->

<button class="testButton" onclick="fncBtn3();" style="width: 100px;">
ボタン小
</button><br />

<button class="testButton" onclick="fncBtn3();" style="width: 150px;">
ボタン中
</button><br />

<button class="testButton" onclick="fncBtn3();" style="width: 200px;">
ボタン大
</button>


<!--ボタンクリック時に動くJavaScript関数-->
<script>
  function fncBtn3(){

    //"testButton"というclassを指定して、
    //JavaScript側でHTML要素を取得
    var arrBtn = document.getElementsByClassName("testButton");

    //取得できたボタンの数だけ、ループを回す
    for(var i=0; i < arrBtn.length; i++){
      //ボタンの幅を一つずつ通知
      alert("ボタン [" + i + "] の幅: " + arrBtn[i].style.width);
    }
  }
</script>

今度は、要素のclassを指定して、JavaScript側でボタンを取得していますね。

今回は、同じclass属性を持ったボタンが複数配置されていますから、取得した配列の中には、複数のボタン要素の情報が格納されています。

そのボタン要素一つ一つの横幅を、alert関数を用いて通知していますね。

このように、ループを回すことによって、getElementsByClassName
getElementsByNameで取得した要素全ての情報を表示したりすることができます。


JavaScriptによるDOMの操作


JavaScriptを使ってDOMを操作する女性

ここまでは、JavaScriptからHTMLの要素を取得する方法を確認しましたね。

今度は、JavaScript側からHTMLの要素に変更を加える例を見てみましょう。

たとえば、以下のようなものです。




<!--HTML上に配置されたボタン-->
<button id="biggerButton" onclick="fncBtn4();" style="width: 150px;">
大きくなぁれ
</button>


<!--ボタンクリック時に動くJavaScript関数-->
<script>
  function fncBtn4(){

    //"biggerButton"というidを持つHTML要素を取得
    var btn = document.getElementById("biggerButton");

    //取得したボタン要素の横幅を読み込む
    var btnWidth = btn.style.width;

    //"px"を除去して数値に変換
    var intBtnWidth = parseInt(btnWidth);

    //取得した値よりも50だけ大きい数値にする
    var intBtnWidth = intBtnWidth + 50;

    //数値をpx付きの文字列に戻す
    btnWidth = intBtnWidth + "px";

    //要素に横幅を設定
    btn.style.width = btnWidth;
  }
</script>

やっている事としては、以下のような流れですね。

  1. ボタンが押される
  2. ボタンの横幅をJavaScript関数内で取得
  3. 取得した横幅に50を加算する
  4. 加算した値を、ボタンの横幅に設定する

上記の「4. 加算した値を、ボタンの横幅に設定する」のように、JavaScript側から、HTML要素の属性値の変更ができるのです。

これは工夫次第で、色々なものが作れる気がしませんか?


また、上記の例で注目して頂きたいのが、青字で書かれたbtnという変数です。

最初にgetElementByIdで取得したボタン要素をbtn変数に格納していますが、それ以降、特にそのbtn変数の中身の再取得は行っていませんね。

btn変数に格納されているオブジェクトの横幅を変更すれば、自動的にHTML側にもその変化が反映されています。

つまり、一度getElementByIdなどで取得した要素は、その取得したJavaScriptの変数に格納されているオブジェクトの属性値を変更することによって、HTML側にも変更が反映されるようになるのです。

実は、getElementByIdなどを使って、JavaScriptからHTMLにアクセスするのは、少し処理時間を要します。

特に時間を要するのが「再描画」の処理です。

上記でも確認したように「再描画」が行われるタイミングは、DOM要素の属性値がJavaScript上で変更された時です。

そのため、getElementByIdを使って取得した要素の属性値を、JavaScript内で頻繁に変更していると、処理が遅くなってしまいます。(そのたびに再描画が行われるため)

したがって、JavaScript側に取得したDOM要素の属性を処理の中で何度も変更するのは、パフォーマンス的に好ましくありません。
細かい計算は通常のJavaScriptの変数を使って一通り済ませた後、描画が必要なタイミングで、一度だけDOM要素の値を変更するのが良いでしょう。

この例ではgetElementByIdを用いて説明をしましたが、getElementsByNamegetElementsByClassNameでも、同様の操作を行うことができます。


JavaScriptライブラリーによるDOM操作


JavaScriptライブラリーについて調べる女子

上記で一通りの説明は終わったのですが、ここでは違ったアプローチから、JavaScriptによるDOM操作について考えてみましょう。

皆様は、JavaScriptライブラリーというものをご存知でしょうか。

分かりやすく言うと、JavaScriptプログラムの部品のようなものです。

世の中には便利なソースコードの部品を公開してくれている人たちが沢山いて、その人たちが作ったソースコードを、呼び出して使わせてもらうことができるのです。

最も有名なJavaScriptライブラリーの一つに、jQueryと呼ばれるものがあります。

このjQueryを用いることによって、上記のJavaScriptによるDOM操作の記述を、より簡潔に行うことができます。


jQueryの導入


ライブラリーなどと言われると、何だか使い始めるまでのセットアップなどが大変そうですが、JavaScriptでのライブラリーの使用は、非常に簡単に始められます。

jQueryの場合は、以下の一文をHTML内に書き加えるだけです。

<script src='http://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js' type='text/javascript'></script>

この一行をHTML内に書き加えるだけで、もうjQueryの利用を始めることができます。

上記の
「src='http://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js'」
という部分が、jQueryのプログラムが置いてある、インターネット上の場所を表しています。
URLで指定されていますね。

今回は、Googleさんが管理しているサーバー内にある、jQueryプログラムの場所を指定させてもらいましたので、そこに置いてあるjQueryのプログラムを用います。
(Google以外にもjQueryを公開している団体も多くありますが、基本的にはどこのものを読み込んでも同じと考えて良いでしょう。)

jQueryを用いたDOM操作


先ほどのボタンが大きくなるJavaScriptを、jQueryを用いて書くと以下のようになります。
jQueryの利点を分かりやすくするため、今回はゆっくり伸びていくアニメーションをつけてみましょう。)



ボタンを押すと、グーーンとボタンの幅が伸びていくのが分かりますね。

上記のようなボタンの動きは、以下のソースコードで実現されています。

<!--HTML上に配置されたボタン-->
<button id="btnForJquery" style="width: 150px;">
大きくなぁれ
</button>


<!--jQueryの読み込み-->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js" type="text/javascript"></script>


<!--ボタン押下時の関数-->
<script>
//idが「btnForJquery」である要素の、クリック時の処理
$("#btnForJquery").click(function(){

  //押されたボタンの幅を取得
  var $this = $(this);
  btnWidth = parseInt($this.css("width"));

  //アニメーションをさせる
  $this.animate({

    //取得した幅よりも50pxだけ伸ばす
    "width": btnWidth + 50 + "px"

  //1000ミリ秒(1秒)かけてアニメーションさせる
  },1000);
});
</script>

どうでしょうか。

jQueryの構文を用いた場合、getElementById("ID名")に当たる部分が、$("#ID名")になっていて、少し短くなっているのが分かりますね。

ただこれだけでは、あまりjQueryの利点は分かりません。

この例でjQueryが特に頑張ってくれているのが、
 $this.animate({
から始まっている、アニメーションの処理ですね。

素のJavaScriptのみを使って、こういったアニメーションを書こうとすると、ループなどを用いて結構めんどくさいソースコードを書く必要がありますが、jQueryを用いた場合は非常に簡潔な記載でできてしまいます。

高度なCSSを用いてアニメーションさせる方法もあるのですが、JavaScriptの議題からは逸れるので、その説明はまたの機会にしましょう。


jQueryの本


もしjQueryに興味が湧いた方は、以下の書籍がオススメです。

と言うのも、自分は新しい技術を勉強する際には、一冊紙の本を買って、大枠を体系的に学ぶようにしています。

下記の書籍は、これまで私が何冊か読んだjQueryの書籍の中で、一番とっつきやすく、分かりやすいと感じたため、ここで紹介させて頂きます。


特に自分がこの本を良いと感じた点は、

  • 具体例が多い
  • 画像が非常に多く、視覚的に分かる

という2点です。

ダラダラ理論だけを説明するスタイルではなく、「作りたいもの」を明確にした上で、それを実現するための方法を教えてくれるので、実践でも使えるスキルが身につくと感じました。

JavaScriptの基本的な部分が分かってきたら、皆様もjQueryの学習に取り掛かってみては如何でしょうか。


まとめ:
JavaScriptからのDOM操作を用いて、動的なWebサイトを作ろう!


仰向けハリネズミ

如何でしたでしょうか?

上記のように、JavaScriptからのDOM操作を用いれば、HTMLに対して、ユーザーの操作に呼応するような動きを加えることができます。

アイデア次第で、ユーザーの心をグッと掴むようなUIが作れるようになるかもしれませんね。

是非皆さんも、ご自身のWebサイトなどを作る際には、JavaScriptからDOMの操作を行って、オリジナルの動きを付けてみてください!


この記事が、少しでも皆様のプログラミング学習の助けになれば幸いです。
最後まで読んで下さり、ありがとうございました。