6章 要素の生成

ここまではHTMLに記述されたDOM構造内の要素のテキストや属性に対して操作をしてきましたが、ここからは、DOM構造自体に変化を与える操作をしていきます。この章では新しい要素を生成してDOM構造に加える方法を学びます。

6.1 要素の生成

さっそく要素を生成してみましょう。createElementという関数を使った方法を紹介します。

var element = document.createElement(tag_name);

引数tag_nameには生成したい要素名(タグ名)を指定します。戻り値は生成された要素オブジェクト(HTMLElement)になります。

実際に要素を生成してみましょう。

//div要素を生成
var div = document.createElement('div');

//テキストを設定
div.textContent = 'hello';

この例ではdiv要素を生成し、テキストを設定しています。しかし、このコードを実行してみればわかりますが、この処理だけでは生成したdiv要素は画面上には表示されません。要素を生成しただけで、DOM構造に追加していないからです。要素はDOM構造に加えて初めて描画されます。

6.2 最後の子要素として追加

要素をDOM構造に加えるためには、要素を「どこに追加するのか」という情報が必要です。どこに追加するかによって使う関数が違います。まずは、ある要素の子要素に追加するappendChildから見てみましょう。

element.appendChild(target);

引数targetには追加する要素を指定します。targetはelementの最後の子要素として追加されます。

具体例を見てみましょう。

<ul>
  <li>item1</li>
  <li>item2</li>
  <li>item3</li>
  <li>item4</li>
</ul>
//li要素を生成
var li = document.createElement('li');

//テキストを設定
li.textContent = 'item5';

//ulを取得
var ul = document.querySelector('ul');

//ulの最後の子要素として追加
ul.appendChild(li);

appendChildを実行すると、item5がDOMに追加され、画面に描画されます。

6.3 要素の直前に追加

appendChildでは最後の子要素として追加されてしまいますが、他の場所に追加したいときもあるでしょう。そこで、今度は他の要素の直前に追加する方法を見ていきましょう。insertBeforeを使います。

以下の例を見てください。

<ul>
  <li>item1</li>
  <li>item3</li>
  <li>item4</li>
</ul>

item3の前にitem2を追加したいとします。

//まずは要素を生成
var li = document.createElement('li');

//テキストを設定
li.textContent = 'item2';

//親要素を取得
var ul = document.querySelector('ul');
//追加したい位置の直後の要素を取得
var li3 = ul.children[1];
//ul下のli3の直前にliを追加
ul.insertBefore(li, li3);

WARNING

注意点としてinsertBeforeはappendChildと同様に親のオブジェクトから呼び出すということです。だから、以下のような書き方は間違いです。

//これは駄目
//親(ul)のメソッドとして呼ばないといけない
li3.insertBefore(li, li3);

ところで、今回の例は以下のようにも書くことができます。

//まずは要素を生成
var li = document.createElement('li');

//テキストを設定
li.textContent = 'item2';

//追加したい位置の直後の要素を取得
var li3 = document.querySelector('ul>li:nth-child(2)');
//li3の直前にliを追加
li3.parentNode.insertBefore(li, li3);

最初の例では親要素(ul)を取得してからchildrenプロパティで挿入場所直後の子要素(li3)を取得しました。しかし、この例では親要素は取得せずにli3をquerySelectorで直接取得しています。そして、insertBefore呼び出し時に、parentNodeを使って親要素(ul)のメソッド呼び出しにしているのです。こうすることによって、より明確にli3の直前に追加するという意図が明確になり、querySelectorで親要素を取得する必要もなくなります。parentNodeのような関連要素の取得はこういうところで役に立つのです。

6.4 innerHTML

DOM要素を作るにはcreateElement以外にも方法があります。innerHTMLというプロパティを使うと要素の生成とDOMへの追加が一度にできます。

element.innerHTML = html_string;

html_stringはHTMLのタグ記法の文字列が使えます。つまりHTMLを書く感覚で使えるのです。当然、属性もHTMLの感覚で書けます。

実際にやってみましょう。

<div id="box"></div>

このdiv要素の中に3つの項目を持ったリストを作りたいとします。以下のような構造を作ると考えてください。

<div id="box">
  <ul id="nav">
    <li>item1</li>
    <li class="active">item2</li>
    <li>item3</li>
  </ul>
</div>

これをcreateElementやappendChildを駆使して作っていくと少々面倒です。しかし、innerHTMLを使うと以下のように、簡単に書くことができます。

//追加したい親要素を取得
var div = document.querySelector('#box');

//子以下のDOM構造を直接生成
div.innerHTML = '<ul id="nav">' +
    '<li>item1</li>' +
    '<li class="active">item2</li>' +
    '<li>item3</li>' +
    '</ul>';

これだけです。HTMLのタグ記法で直接代入しているのがわかると思います。さらに、createElementとappendChildのように、要素生成とDOM構造への追加が分離していないこともわかり易いポイントとなっています。

innerHTMLに値を文字列を代入すると既存のDOM要素はすべて消えることに注意しましょう。

例えば、以下のHTMLがあるとします。

<div id="box">
  <h1>タイトル</h1>
</div>

ここでh1要素は残しつつ、p要素を追加したいとします。このように、既に他の要素が存在する状態で末尾に追加したい場合は、innerHTMLに再代入するのではなく追記するようにします。

//+=で追記する
div.innerHTML += '<p>テキスト</p>’;

ところで、最新のJavaScript環境ではTemplate stringがあります。対応ブラウザであれば、innerHTMLによるDOM生成をよりシンプルに書くことができます。

先程の3つの項目を持ったリストを追加する例をTemplate stringを使って書き直すと以下のようになります。

//追加したい親要素を取得
var div = document.querySelector('#box');

//子以下のDOM構造を直接生成
div.innerHTML = `
  <ul id="nav">
    <li>item1</li>
    <li class="active">item2</li>
    <li>item3</li>
  </ul>
`;

文字列をバッククォートで囲むと改行をそのまま出力することができるので、1行ずつ文字列の連結をする必要がありません。本当にHTMLを書く感覚でDOM構造を生成できます。

6.5 まとめ

本章では、要素を生成する方法について学びました。createElementで要素を生成し、appendChildやinsertBeforeでDOMに追加する方法、innerHTMLで直接タグ記法で要素の生成と追加をする方法。どちらも覚えておきましょう。

Last Updated: 2018-5-10 17:49:38