第5回 DOMを使ってHTMLを自由自在に書き換える

 これまでは,すでにHTML上に存在している要素をDOMを使って参照する方法を見てきました。しかし,参照するだけではページに何も変化をつけることはできません。今回は,HTML上に新たに要素を追加したり,削除する手法を見ていきましょう。

要素を新たに追加する

 要素を新たに作るには,まずcreateElementメソッドを使います。引数に要素名を与えることで,指定の要素が作られ,その要素ノードオブジェクトが返されます。createElementメソッドはdocumentオブジェクトに既定されたメソッドですので,次のように使います。

var img = document.createElement("img");
img.src = "sample.png";

 このサンプルでは,次の要素を生成したことになります。

<img src="sample.png">

 しかし,この状態ではまだ画面上には新たに生成したimg要素が表示されることはありません。まだ,仮想的に要素を作ったに過ぎないのです。この仮想的に生成された要素をHTML上に表示させるためには,appendChildメソッドを使います。

document.body.appendChild(img);

 appendChildメソッドは,新たに生成した要素ノードオブジェクトを引数に与えると,それを画面上に表示します。このメソッドは,メソッド名の通り,子要素として新たな要素を追加します。このサンプルでは,BODY要素の子要素としてIMG要素を追加したことになります。

テキストを追加する

 例えば,A要素を新たに追加したい場合は,テキストも一緒に追加しなければいけません。テキストの部分は,テキストノードとしてA要素の子要素となります。

 まずは,createTextNodeメソッドを使ってテキストノードを生成します。createTextNodeメソッドは,引数にテキストを与えると,そのテキストノードオブジェクトを返します。新たに生成されたテキストノードオブジェクトを,appendChildメソッドを使って,A要素の要素ノードオブジェクトに追加します。

 実際に,A要素をBODY要素に追加する手順は次のようになります。

/* A要素を新たに生成 */
var anchor = document.createElement("a");
/* A要素にhref属性をセット */
anchor.href = "http://www.w3.org/";
/* テキストノードを新たに生成 */
var text = document.createTextNode("W3C");
/* テキストノードをA要素の子要素として追加 */
anchor.appendChild(text);
/* 画面表示 */
document.body.appendChild(anchor);

要素を削除する

 要素を削除するには,removeChildメソッドを使います。次のようなHTMLを想定しましょう。

<div id="box"><img src="sample.png" id="pic"></div>

 id属性に"box"がセットされたDIV要素の中に,id属性に"pic"がセットされたIMG要素があります。IMG要素を削除するには,次のようなコードとなります。

/* DIV要素のノードオブジェクト */
var box = document.getElementById("box");
/* IMG要素のノードオブジェクト */
var pic = document.getElementById("pic");
/* IMG要素を削除 */
box.removeChild(pic);

 removeChildメソッドは,引数に削除したい要素のノードオブジェクトを与えます。しかし,このメソッドは名前の通り,子要素を削除するメソッドです。そのため,削除したい要素の親要素に対して適用しなければいけません。そのため,このサンプルでは,親要素に相当するDIV要素のノードオブジェクトに対してremoveChildメソッドを使っています。

 しかし,要素を削除するために,いちいち親要素をノードオブジェクトを用意するのは面倒です。そのため,実際には,parentNodeプロパティを使って,親要素を参照します。

/* IMG要素のノードオブジェクト */
var pic = document.getElementById("pic");
/* IMG要素を削除 */
pic.parentNode.removeChild(pic);

 こうすることで,削除したい要素のノードオブジェクトさえ得られれば,その要素を削除することができるようになります。

ケーススタディ

 では,これまで見てきた要素の追加や削除を,実際のケースを想定して使ってみましょう。

 ここでは,良くある「同意する」にチェックを入れて次へ進むことができるフォームを例にあげます。

<form action="#" method="post" id="agreeform">
<input type="checkbox" name="agree" value="1" id="agree">
同意する。
</form>

 このフォームは,「同意する」と書かれたチェックボックスが表示されるだけで,次へ進むボタンがありません(図1)。

図1:チェックが入っていない状態

 この「同意する」と書かれたチェックボックスにチェックを入れると,「次へ」と書かれたボタンが表示され(図2),そして,チェックを外すとボタンが削除されるという動きを作ってみましょう。

図2:チェックを入れた状態

window.onload = function() {
  /* チェックボックス */
  var agree = document.getElementById("agree");
  /* フォーム */
  var agreeform = document.getElementById("agreeform");
  /* チェックボックスにonclickイベントハンドラをセット */
  agree.onclick = function() {
    if(agree.checked == true) {
      /* チェックが入ったときはボタンを生成表示 */
      var btn = document.createElement("input");
      btn.type = "submit";
      btn.value = "次へ";
      btn.id = "btn";
      agreeform.appendChild(btn);
    } else {
      /* チェックが外されたときはボタンを削除 */
      var btn = document.getElementById("btn");
      if( btn ) {
        btn.parentNode.removeChild(btn);
      }
    }
  };
};

 まずは,ブラウザにHTMLがロードされたときに,チェックボックスにonclickイベントハンドラがセットされるよう,スクリプト全体をwindow.onload = function() {...} に記述します。

 チェックボックスを成すINPUT要素のノードオブジェクトをagreeに,そして,FORM要素のノードオブジェクトをagreeformに格納しておきます。

 次に,チェックボックスがクリックされたときに,画面上に動きを与えるための処理をセットするために,チェックボックスagreeにonclickイベントハンドラをセットします。agree.onclick = function() {...}がそれに相当します。これで,チェックボックスにチェックが入れられたり,また逆に,チェックが外されれば,この中に記述したコードが実行されるようになります。

 チェックボックスにチェックが入っているか,それともチェックが入っていないのかを調べるために,checkedプロパティを使います。agree.checkedがtrueであれば,チェックが入れられていることを表します。この場合は,sbumitタイプのINPUT要素を新たに生成し,FORM要素の中に表示します。もしチェックが入っていなければ,removeChildメソッドを使って,ボタンを削除してしまいます。

 このケーススタディではチェックボックスとボタンという組み合わせをご紹介しましたが,このケースに限らず,要素の追加と削除は様々なシーンで活用できます。ちょっとしたアイデアで,サイト訪問者に便利に使っていただける機能をページに組み込むことができます。ぜひ,実践で活用してください。